C++ 模板类的类成员的专门化
让C++ 模板类的类成员的专门化,c++,templates,inner-classes,C++,Templates,Inner Classes,让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 }; }; t
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 false" << 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;
}
看到了
编译错误是:
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
的部分专门化完全掩盖了构造函数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 false";
}
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;
}
template <bool rgb>
struct colors_type;
template <>
struct colors_type<true> {
enum : std::size_t { red, green, blue };
};
template <>
struct colors_type<false> {
enum : std::size_t { cyan, magenta, yellow, black };
};
template <bool rgb, int i>
struct A {
using colors = colors_type<rgb>;
A();
};
#包括
模板
结构颜色(u型),;
模板
结构颜色\u类型{
结构颜色{enum:std::size_t{red,green,blue};};
};
模板
结构颜色\u类型{
结构颜色{enum:std::size_t{青色、品红色、黄色、黑色};};
};
模板
结构A:公共颜色\u类型{
A();
};
模板
A::A()
{
如果(rgb){
std::cout这是指定语言的方式:
- 您可以显式地专门化类模板的成员类(请参阅)
- 可以为类提供部分专门化(请参见)
对[temp.class.spec]感兴趣:
类模板的部分专门化提供了模板的替代定义,而不是主定义
每个类模板部分专业化是一个不同的模板,应为模板部分专业化的成员提供定义
我认为您提供的继承技巧是最好的技巧,或者至少是最常用的技巧。正如Oliv的回答所解释的,该语言不允许嵌套类的部分专门化
在这种情况下,您还可以通过将内部类设置为类型别名来获得所需的结果,而无需继承:
#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 false";
}
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;
}
template <bool rgb>
struct colors_type;
template <>
struct colors_type<true> {
enum : std::size_t { red, green, blue };
};
template <>
struct colors_type<false> {
enum : std::size_t { cyan, magenta, yellow, black };
};
template <bool rgb, int i>
struct A {
using colors = colors_type<rgb>;
A();
};
模板
结构颜色(u型),;
模板
结构颜色\u类型{
enum:std::size_t{红色、绿色、蓝色};
};
模板
结构颜色\u类型{
enum:std::size_t{青色、洋红、黄色、黑色};
};
模板
结构A{
使用颜色=颜色\u类型;
A();
};
在本例中,这两种解决方案没有太多明显的优点或缺点,但在一些更复杂的情况下,其中一种可能更容易或更清晰(尽管我猜在这些更一般的用例中继承更有用)您的输出总是rgb true
。@Phil1970 ops,已更正。