我想阻止某些类型的模板实例化。我想在库中实现一个算法,它只适用于实数,而不适用于复杂或整数类型。因此,使用浮动/双/长双/强强类的用户实例化应该是可以的,但不能发生complex<float>。
专门化会产生代码膨胀,而代码将永远不会被使用。(我只能生成只抛出异常的ctors )。
template<typename T>
void work (T & result, T const & input) { /* work for any real type */ }理想情况下,应该有一个编译器消息,上面写着“这个.实例化是不允许的”。
允许的模板的显式列表将限制太大。
发布于 2019-05-24 09:04:59
可以使用static_assert生成所需的确切编译时错误消息:
#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,您可以将它写得更短一点:
static_assert(std::is_floating_point_v<T>, "Only floating point types are allowed.");发布于 2019-05-24 09:06:46
如果要防止对特定类型进行实例化,可以将模板的特定专门化定义为deleted。
防止使用T=int实例化的最小示例
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实例化。
error: use of deleted function 'void work(T&, const T&) [with T = int]'
16 | work(i1, i2); //Doesn't work发布于 2019-05-24 09:19:16
为了完整起见,也有SFINAE。
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上下文中使用参数调用。将检查放入函数模板的签名中是实现此目的的唯一方法。
https://stackoverflow.com/questions/56289110
复制相似问题