c++ - 约束白名单类型模板函数的更好方法,SFINAE?

标签 c++ templates c++17 sfinae template-argument-deduction

我想制作一个特征/界面,例如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/

相关文章:

javascript - EJS 模板 .render() 返回函数而不是 HTML

c++ - gcc - 如何在结构定义中组合 __attribute__((dllexport)) 和 [[nodiscard]]?

c++ - 重载 << 运算符

c++ - 如何将第 3 方 C 库添加到 tensorflow?

c++ - 错误: no matching function for call to (unsolvable?)

javascript - 使用js脚本生成<head>和&lt;footer&gt;

c++ - 如何将一个 std::vector move 附加到另一个?

c++ - 在 Pybind11 中使用自动转换

c++ - 在 C++ 中实现哈希表(插入和延迟删除)

c++ - 为 C++ ostream 自定义流缓冲区