基于整数常量比较的模板专业化

时间:2019-03-11 00:47:29

标签: c++ templates sfinae

这是我拥有的东西:

template <typename T, std::size_t dim>
struct vector;

template <std::size_t dim>
struct vector<float, dim>
{
    // I want this implementation for dim <= 4
}

template <std::size_t dim>
struct vector<float, dim>
{
    // I want this implementation for dim > 4
}

int main() {
    vector<float, 3> v1; // should instantiate first one
    vector<float, 7> v2; // should instantiate second one
}

现在,这当然不是可行的示例,因为我无法使其正常工作。我不知道如何安排专业模板签名。它们现在是相同的模板参数,将不会编译。不知何故,某种SFINAE应该输入图片,但我不允许在部分专业化上使用默认模板参数。

我可以使用constexpr if来处理代码选择,而只使用一种专业化。但是我相信,拥有这些专业的单独专长会使事情变得更易读和易管理。

您将如何实现?

3 个答案:

答案 0 :(得分:6)

您可以使用SFINAE来实现。在未专业化的模板上添加一个额外的模板参数,然后确保在特定条件下将其与您的专业化匹配。

template <typename T, std::size_t dim, typename = void>
struct vector;

template <std::size_t dim>
struct vector<float, dim, std::enable_if_t<(dim <= 4)>>
{
    // I want this implementation for dim <= 4
};

template <std::size_t dim>
struct vector<float, dim, std::enable_if_t<(dim > 4)>>
{
    // I want this implementation for dim > 4
};

int main() {
    vector<float, 3> v1; // should instantiate first one
    vector<float, 7> v2; // should instantiate second one
}
如果传递给它的条件为真,

std::enable_if_t将默认推导为void。如果不是这样,它将不会导致导致替换失败的任何事情,从而为其他模板的匹配铺平道路。

std::enable_if_t需要c++14,但是自typename std::enable_if<condition>::type起您就可以使用c++11

答案 1 :(得分:3)

可能的解决方案,使用附加层。我们为此参数使用其他bool模板参数和特殊化。可以用于С++ 11以下的版本。

template <typename T, std::size_t dim, bool moreThanFour>
struct vectorImpl;

template <std::size_t dim>
struct vectorImpl<float, dim, false>
{
   // I want this implementation for dim <= 4
};

template <std::size_t dim>
struct vectorImpl<float, dim, true>
{
   // I want this implementation for dim > 4
};

template <typename T, std::size_t dim>
struct vector : public vectorImpl < T, dim, (dim > 4) > {};

int main() {
   vector<float, 3> v1; // should instantiate first one
   vector<float, 7> v2; // should instantiate second one
}

答案 2 :(得分:1)

有了概念,您可以简单地编写:

template <typename T, std::size_t dim>
struct vector;

template <std::size_t dim>
    requires (dim <= 4)
struct vector<float, dim>
{
    // I want this implementation for dim <= 4
};

template <std::size_t dim>
    requires (dim > 4)
struct vector<float, dim>
{
    // I want this implementation for dim > 4
};

godbolt上查看

我们只需要等待他们