根据成员的存在创建不同的模板版本



我想有一个像这样的模板化函数:

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

最新更新