简体   繁体   English

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

[英]Template specialization based on integer constant comparison

Here is something I have: 这是我有的东西:

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
}

Right now, this is not a working example of course, since I can't get it to work. 现在,这当然不是一个有效的例子,因为我无法让它发挥作用。 I don't know how to arrange the specialization template signatures. 我不知道如何安排专业化模板签名。 They are same template arguments right now and won't compile. 它们现在是相同的模板参数,不会编译。 Somehow, a kind of SFINAE should enter the picture I guess but I am not allowed to have default template arguments on partial specializations. 不知何故,一种SFINAE应该进入我想的图片但我不允许在部分特化上有默认的模板参数。

I could use constexpr if to handle the code selection and have one specialization instead. 我可以使用constexpr if来处理代码选择并改为使用一个特化。 But I believe, having seperate specializations for these makes things more readable and manageable. 但我相信,对这些进行单独的专业化会使事情更具可读性和可管理性。

How would you achieve this? 你会如何实现这一目标?

You can achieve this by using SFINAE. 您可以使用SFINAE实现此目的。 You add an extra template parameter to the unspecialized template, then you make sure to match it in your specialization for a certain condition. 您将一个额外的模板参数添加到非专业化模板,然后确保在特定条件的专业化中匹配它。

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 will deduce to void by default if the condition passed to it is true. 如果传递给它的条件为真,则std::enable_if_t将默认推导为void If not, it will not deduce to anything resulting in substitution failure leaving the way for any other template to match. 如果没有,它将不会导致导致替换失败的任何事情,从而使任何其他模板匹配。

std::enable_if_t requires c++14 but you can use typename std::enable_if<condition>::type since c++11 . std::enable_if_t需要c++14但是你可以使用typename std::enable_if<condition>::type c++11

Possible solution using additional layer. 使用附加层的可能解决方案 We use additional bool template argument and specialization for this arg. 我们对此arg使用额外的bool模板参数和特化。 Can be used for version less than С++11. 可用于低于С++ 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
}

With concepts you can simply write: 使用概念,您可以简单地写:

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

See it on godbolt godbolt看到它

We just have to wait for them 我们只需要等待它们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM