我想有一个像这样的模板化函数:
template <typename T>
void ReadHelper(T vector_array[])
{
// some code
}
其中T
为某种结构。但是这个结构有两个不同的版本:
struct type1 {
float data;
}
struct type2 {
float data;
bool valid;
}
我希望ReadHelper
能够设置valid
标志。编写两个不同的模板化函数以正确处理这两种类型的结构的好方法是什么?我当然可以为所有类型编写重载版本,但这相当乏味。有没有如何正确地设置模板来做到这一点?也许SFINAE ?
SFINAE绝对是一个解决方案!我使用模板检查是否存在一个类成员函数?作为参考。
这里有一个例子,你可能会这样做。has_valid
型是重要的;我用它来做函数分派,但你也可以用其他方式。在您的情况下,您只需从读取助手中调用set_valid(vector_array[i])
或其他内容。
// SFINAE check for if T has member valid
// note this doesn't check that the member is a bool
template<class T>
class has_valid
{
template<class X>
static std::true_type check(decltype(X::valid));
// Use this version instead if you want to
// check if X::valid is explicitly a bool
/*
template<class X>
static std::true_type check(std::enable_if_t<
std::is_same_v<decltype(X::valid), bool>,
bool
>);
*/
template<class X>
static std::false_type check(...);
public:
using type = decltype(check<T>(true));
constexpr static auto value = type();
};
// Friendly helpers
template<class T>
using has_valid_t = typename has_valid<T>::type;
template<class T>
constexpr static auto has_valid_v = has_valid<T>::value;
// Function dispatcher; call set_valid, which will use has_valid_t to
// dispatch to one of the overloads of dispatch_set_valid, where you can
// either set or not set the value as appropriate
template<class T>
void dispatch_set_valid(T& t, std::false_type)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<class T>
void dispatch_set_valid(T& t, std::true_type)
{
t.valid = true;
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<class T>
void set_valid(T& t)
{
dispatch_set_valid(t, has_valid_t<T>());
}
在编译器资源管理器上查看:https://godbolt.org/z/sqW17WYc6