我想制作一个特征/界面,例如is_good
,并针对其规范实现我的通用函数。
在有关 SFINAE 的一些在线资源的帮助下,我想出了以下代码。
template<class C>
struct is_good: std::false_type
{
};
template<>
struct is_good<A<double, 2>>: std::true_type
{
};
template<>
struct is_good<B<double, 2, 3>>: std::true_type
{
};
template<template<class> class C, class T>
using check_constraints = std::enable_if_t<C<T>::value, bool>;
}
我的通用函数是这样定义的:
template<class T, template<class> class C = is_good,
typename = check_constraints<C, T>>
void compute(const T& t) {}
在使用中
// works
compute(A<double,2>());
compute(B<double,2, 3>());
// should not compile.
compute(B<double,5, 6>());
不过,好像有点麻烦。我必须在前面加上
template<class T, template<class> class C = is_good,
typename = check_constraints<C, T>>
我计划通用化的所有函数。
有没有更好的方法?
更新
这个问题的基础是,假设我知道我的函数体使用 A
& B
& C
类型,如何我可以定义我的函数吗?
例如,在其他语言中,也许你可以这样做
using T = Union{A, B, C};
void compute(T t){...}
# works with A
compute(A());
# works with B
compute(B());
无论 A、B、C
看起来如何。
最佳答案
你的问题不清楚。但是,如果 is_2d
必须在所有函数中,为什么不将其移动到 check_constraints
中呢?引用:https://gcc.godbolt.org/z/s9Jql-
template<class T>
using check_constraints = std::enable_if_t<is_2d<T>::value, bool>;
template<class T, typename = check_constraints<T>>
void compute(const T& t){
works(t);
}
更新
如果你只是想要一个允许类型的列表,下面的更好,因为你有 c++17。 https://gcc.godbolt.org/z/kJN7hu
#include<type_traits>
template<class... Types>
struct TypeContainer{
template<class T>
using contains = typename std::disjunction< std::is_same<T,Types>... >::type;
};
using allowed_types = TypeContainer<
int,
float
>;
template<class T, typename = std::enable_if_t<allowed_types::contains<T>::value>>
void compute(const T& t);
void foo() {
int i;
compute(i);
//char c; compute(c);
}
关于c++ - 约束白名单类型模板函数的更好方法,SFINAE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54428110/