模板类内部的本地类的专业化

问题描述 投票:2回答:1

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;
}

查看live on Coliru

([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;
}

查看live on Coliru

编译错误是:

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;
}

查看live on Coliru

  • 为什么仅当我完全封闭化类的模板参数(第一代码)时才对内部结构进行特殊化,而当我仅对它们的一部分进行特殊化(第二代码)时不对它进行特殊化?

  • 除了继承技巧(第四代码)之外,还有其他解决方案吗?

让A为包含内部结构的模板类。我想专门化内部结构(仅此而已),具体取决于A的模板参数。以下代码似乎可以正确执行...

c++ templates inner-classes
1个回答
0
投票

这是指定语言的方式:

© www.soinside.com 2019 - 2024. All rights reserved.