具有常量值的C++模板专业化

tad*_*man 33 c++ templates template-specialization

给定一个模板参数的数值常量,是否有一种直接的方法来定义C++模板类的部分特化?我正在尝试为特定类型的模板组合创建特殊构造函数:

template <typename A, size_t B> class Example
{
    public:
        Example() { };

        A value[B];
};

template <typename A, 2> class Example
{
    public:
        Example(b1, b2) { value[0] = b1; value[1] = b2; };
};
Run Code Online (Sandbox Code Playgroud)

此示例将无法编译,Expected identifier before numeric constant在第二个定义中返回错误.

我已经看过这里和其他地方的一些例子,但大多数似乎都围绕着一个类型而不是一个常量.

编辑:

寻找一种编写有条件使用的构造函数的方法,其功能如下:

template <typename A, size_t B> class Example
{
    public:
        // Default constructor
        Example() { };

        // Specialized constructor for two values
        Example<A,2>(A b1, A b2) { value[0] = b1; value[1] = b2; };

        A foo() {
          A r;

          for (size_t i = 0; i < b; ++b)
            r += value[i];

          return r;
        }

        // Hypothetical specialized implementation
        A foo<A, 2>() {
          return value[0] + value[1];
        }

        A value[B];
};
Run Code Online (Sandbox Code Playgroud)

Foo*_*Bah 20

您需要将专业化放在正确的位置:

template <typename A> class Example<A,2>
Run Code Online (Sandbox Code Playgroud)

如果要创建子类:

template <typename A> class ExampleSpecialization : public Example<A,2>
Run Code Online (Sandbox Code Playgroud)

专门用于typedef的行为类似于专门用于整数参数的行为.


Mar*_*lon 9

我认为这可能有效:

#include <iostream>

template <typename A, size_t B>
class Example {
public:
    Example()
    {
        Construct<B>(identity<A, B>());
    }

    A foo()
    {
        return foo<B>(identity<A, B>());
    }

private:
    template <typename A, size_t B>
    struct identity {};

    template <size_t B>
    void Construct(identity<A, B> id)
    {
        for (size_t i = 0; i < B; ++i)
        {
            value[i] = 0;
        }
        std::cout << "default constructor\n";
    }

    template <size_t B>
    void Construct(identity<A, 2> id)
    {
        value[0] = 0;
        value[1] = 0;
        std::cout << "special constructor\n";
    }

    template <size_t B>
    A foo(identity<A, B> id)
    {
        A r = 0;
        for (size_t i = 0; i < B; ++i)
        {
            r += value[i];
        }
        std::cout << "default foo\n";
        return r;
    }

    template <size_t B>
    A foo(identity<A, 2> id)
    {
        std::cout << "special foo\n";
        return value[0] + value[1];
    }

    A value[B];
};

int main()
{
    Example<int, 2> example; // change the 2 to see the difference
    int n = example.foo();
    std::cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

对不起,我只是从我的测试项目中复制并粘贴它.它在某种程度上并不是真正的"专业化",它只是调用专用函数的重载.我不确定这是不是你想要的,因为这不是很优雅.


Jer*_*fin 5

如果有内存,它应该更像:

template <typename A, size_t B> class Example
{
    public:
        Example() { };

        A value[B];
};

template <typename A> class Example<A, 2>
{
    public:
        Example(A b1, A b2) { value[0] = b1; value[1] = b2; };
};
Run Code Online (Sandbox Code Playgroud)

我不认为这是完全可以接受的-没有定义专业版本b1和/或b2专业版本的类型的内容。

编辑[基于已编辑的问题]:是的,模板专业化会产生一种新类型,该类型与它所基于的专业化基础并没有真正的关系。特别是,两者共享任何实现。根据非类型参数的值,您不能(通过专门化类模板)产生使用两个不同ctor之一的单一类型。