让A
是包含内部struct
的模板类。我想专门研究内部结构(仅此而已),具体取决于A
的模板参数。以下代码似乎可以正确完成此工作:
#include <iostream>
template <bool rgb>
struct A {
struct colors;
A();
};
template <>
struct A<true>::colors { enum : std::size_t { red, green, blue }; };
template <>
struct A<false>::colors { enum : std::size_t { cyan, magenta, yellow, black }; };
template<bool rgb>
A<rgb>::A()
{
if (rgb) {
std::cout << "rgb true" << std::endl;
}
else {
std::cout << "rgb true" << std::endl;
}
}
int main()
{
using colors_true = A<true>::colors;
using colors_false = A<false>::colors;
A<true> at{};
A<false> af{};
std::cout << colors_true::red << std::endl;
std::cout << colors_false::yellow << std::endl;
}
([A
的构造函数只是为了说明我只是专门研究A::colors
)
现在,考虑A
包含附加模板参数的情况。我想模仿上面的代码,仅专门使用bool
参数。但是,以下代码无法编译:
#include <iostream>
template <bool rgb, int i>
struct A {
struct colors;
A();
};
template <int i>
struct A<true, i>::colors { enum : std::size_t { red, green, blue }; };
template <int i>
struct A<false, i>::colors { enum : std::size_t { cyan, magenta, yellow, black }; };
template<bool rgb, int i>
A<rgb, i>::A()
{
if (rgb) {
std::cout << "rgb true";
}
else {
std::cout << "rgb true";
}
std::cout << " i = " << i << std::endl;
}
int main()
{
using colors_true = A<true, 2>::colors;
using colors_false = A<false, 5>::colors;
A<true, 2> at{};
A<false, 5> af{};
std::cout << colors_true::red << std::endl;
std::cout << colors_false::yellow << std::endl;
}
编译错误是:
main.cpp:10:20: error: invalid class name in declaration of 'class A<true, i>::colors'
10 | struct A<true, i>::colors { enum : std::size_t { red, green, blue }; };
| ^~~~~~
main.cpp:13:21: error: invalid class name in declaration of 'class A<false, i>::colors'
13 | struct A<false, i>::colors { enum : std::size_t { cyan, magenta, yellow, black }; };
| ^~~~~~
A
的部分专业化,如以下代码所示>>
#include <iostream> template <bool rgb, int i> struct A { struct colors; A(); }; template <int i> struct A<true, i> { struct colors { enum : std::size_t { red, green, blue }; }; }; template <int i> struct A<false, i> { struct colors { enum : std::size_t { cyan, magenta, yellow, black }; }; }; template<bool rgb, int i> A<rgb, i>::A() { if (rgb) { std::cout << "rgb true"; } else { std::cout << "rgb true"; } std::cout << " i = " << i << std::endl; } int main() { using colors_true = A<true, 2>::colors; using colors_false = A<false, 5>::colors; A<true, 2> at{}; A<false, 5> af{}; std::cout << colors_true::red << std::endl; std::cout << colors_false::yellow << std::endl; }
也不起作用。看到它live on Coliru。在代码编译时,
A
的部分专业化完全掩盖了构造函数A::A()
,如输出所示。换句话说,在上面的代码中,编译器选择了A
的两个部分专用的版本,其中未明确定义构造函数。
作为一种解决方法,我发现可以使用继承:
#include <iostream>
template <bool rgb>
struct colors_type;
template <>
struct colors_type<true> {
struct colors { enum : std::size_t { red, green, blue }; };
};
template <>
struct colors_type<false> {
struct colors { enum : std::size_t { cyan, magenta, yellow, black }; };
};
template <bool rgb, int i>
struct A : public colors_type<rgb> {
A();
};
template<bool rgb, int i>
A<rgb, i>::A()
{
if (rgb) {
std::cout << "rgb true";
}
else {
std::cout << "rgb true";
}
std::cout << " i = " << i << std::endl;
}
int main()
{
using colors_true = A<true, 2>::colors;
using colors_false = A<false, 5>::colors;
A<true, 2> at{};
A<false, 5> af{};
std::cout << colors_true::red << std::endl;
std::cout << colors_false::yellow << std::endl;
}
为什么仅当我完全封闭化类的模板参数(第一代码)时才对内部结构进行特殊化,而当我仅对它们的一部分进行特殊化(第二代码)时不对它进行特殊化?
除了继承技巧(第四代码)之外,还有其他解决方案吗?
让A为包含内部结构的模板类。我想专门化内部结构(仅此而已),具体取决于A的模板参数。以下代码似乎可以正确执行...
这是指定语言的方式: