2016-06-20 20 views
3

で失敗に:C++の静的int型デフ二重にネストされたテンプレートクラスには、次のコードで打ち鳴らす++とg ++

struct my_symbols { 
    enum class syms { symb_0_0, symb_0_1 }; 
}; 
template 
< typename SymbolEnums 
> 
struct outer { 
    using syms_0 = typename SymbolEnums ::syms; 
    template <syms_0 AnSym0, int Int> 
    struct inner { 
    static int const val; 
    }; 
}; 

template 
< typename SymbolEnums 
> 
template 
< typename outer<SymbolEnums>::syms_0 AnSym0 
, int Int 
> 
int const outer<SymbolEnums>::inner<AnSym0, Int>::val = Int; 

int main() { 
    return 
     outer<my_symbols>:: 
     inner<my_symbols::syms::symb_0_1, 1>::val; 
} 

私はgcc5.2.0と、取得:非テンプレート「int型の

テンプレート定義をouter_tmpl :: inner_tmpl :: val ' val = Int; ^

とclang3.8.0で、私が手: 'outer_tmpl :: inner_tmpl ::'

ネストされた名前指定 宣言は、クラス、クラステンプレートまたはクラステンプレート部分的に言及していないために専門化 val = Int; ^

コードを修正するにはどうすればよいですか?

TIA。

答えて

1

私は正確にはわからないなぜ投稿されたコードが機能しません。私は答えがC + +標準名のルックアップ規則の深いところにあると考えています。これは信じられないほど複雑です。もちろん、これは実際にはコンパイラのバグではないと仮定します。ここの誰かがおそらく知っているでしょう。

以下の「同等の」例は、GCC 5.2.0およびClang 3.8でコンパイルされます。あなたの状況に適しているかもしれません。

例1:使用constexprと、クラスの初期化

struct my_symbols { 
    enum class syms { symb_0_0, symb_0_1 }; 
}; 

template<typename SymbolEnums> 
struct outer { 

    using syms_0 = typename SymbolEnums::syms; 

    template <syms_0 AnSym0, int Int> 
    struct inner { 
    static constexpr int val = Int; 
    }; 
}; 

int main() { 
    return outer<my_symbols>::inner<my_symbols::syms::symb_0_1, 1>::val; 
} 

例2:ネストされたテンプレート型パラメータを微調整

struct my_symbols { 
    enum class syms { symb_0_0, symb_0_1 }; 
}; 

template<typename SymbolEnums> 
struct outer { 

    using syms_0 = typename SymbolEnums::syms; 

    template <syms_0 AnSym0, int Int> 
    struct inner { 
    static int const val; 
    }; 
}; 

template<typename SymbolEnums> 
template<typename SymbolEnums::syms AnSym0, int Int> 
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^ 
int const outer<SymbolEnums>::inner<AnSym0, Int>::val = Int; 

int main() { 
    return outer<my_symbols>::inner<my_symbols::syms::symb_0_1, 1>::val; 
} 
+0

どうもありがとうございましたバレット。したがって、ネストされたsyms_0を使用する代わりに、SymbolEnums :: symsを使用するだけです。あなたが言うように、それはバグかもしれないし、言語のあいまいなルールかもしれません:( – user1681377

関連する問題