With following code:
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;
}
I get, with gcc5.2.0:
template definition of non-template 'int outer_tmpl::inner_tmpl::val' val=Int; ^
and with clang3.8.0, I get:
nested name specifier 'outer_tmpl::inner_tmpl::' for declaration does not refer into a class, class template or class template partial specialization val=Int; ^
How can I correct the code?
TIA.
I do not know exactly why the posted code does not work. I suspect the answer lies deep within the C++ Standard name lookup rules, which are incredibly complicated -- assuming, of course, that this is not actually a compiler bug. Someone else here probably knows.
The following "equivalent" examples compile on GCC 5.2.0 and Clang 3.8. They may or may not be suitable for your situation.
Example 1: Use constexpr
and in-class initialization
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;
}
Example 2: Tweak the nested template type parameter
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.