首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从模板实例化中包含和排除类型

问从模板实例化中包含和排除类型
EN

Stack Overflow用户
提问于 2019-05-24 08:55:08
回答 3查看 69关注 0票数 2

我想阻止某些类型的模板实例化。我想在库中实现一个算法,它只适用于实数,而不适用于复杂或整数类型。因此,使用浮动/双/长双/强强类的用户实例化应该是可以的,但不能发生complex<float>。

专门化会产生代码膨胀,而代码将永远不会被使用。(我只能生成只抛出异常的ctors )。

代码语言:javascript
复制
template<typename T>
void work (T & result, T const & input) { /* work for any real type */ }

理想情况下,应该有一个编译器消息,上面写着“这个.实例化是不允许的”。

允许的模板的显式列表将限制太大。

EN

回答 3

Stack Overflow用户

发布于 2019-05-24 09:04:59

可以使用static_assert生成所需的确切编译时错误消息:

代码语言:javascript
复制
#include <type_traits>

template<typename T>
void work (T & result, T const & input)
{
    static_assert(std::is_floating_point<T>::value, "Only floating point types are allowed.");

    // ...
}

如果您使用的是C++17,您可以将它写得更短一点:

代码语言:javascript
复制
static_assert(std::is_floating_point_v<T>, "Only floating point types are allowed.");
票数 3
EN

Stack Overflow用户

发布于 2019-05-24 09:06:46

如果要防止对特定类型进行实例化,可以将模板的特定专门化定义为deleted。

防止使用T=int实例化的最小示例

代码语言:javascript
复制
template<typename T>
void work (T & result, T const & input) { (void)result; (void)input; }


template<>
void work (int & result, int const & input) = delete;

int main()
{
    float f1 = 3.14;
    float f2 = 1.414;
    work(f1, f2); //works

    int i1 = 1;
    int i2 = 2;
    work(i1, i2); //Doesn't work

}

编译器将抱怨使用int实例化。

代码语言:javascript
复制
error: use of deleted function 'void work(T&, const T&) [with T = int]'
   16 |     work(i1, i2); //Doesn't work

演示

票数 2
EN

Stack Overflow用户

发布于 2019-05-24 09:19:16

为了完整起见,也有SFINAE。

代码语言:javascript
复制
template<typename T>
auto work (T & result, T const & input) -> std::enable_if_t<std::is_floating_point_v<T>>
{
  // ..
}

省略void是因为它是默认类型,enable_if_t解析到条件保持时。这只是一个文体上的选择。

这里的不同之处在于,这个函数甚至不会被认为存在于重载解析中。因此,您可以检查work是否可以在其他SFINAE上下文中使用参数调用。将检查放入函数模板的签名中是实现此目的的唯一方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56289110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档