我可以使用类型特征重载函数吗?

Tre*_*key 13 c++ templates type-traits template-meta-programming c++11

比方说,我有六种类型,它们各自属于一个概念类别.
这是一个显示这个的图表:

类型A,B和C包装在名为


或者也许是一个更具体的例子: Apple,Orange和Banana都是Fruit. 胡萝卜,洋葱和卷心菜都是蔬菜


我想编写两个函数来处理所有6种类型.
"类别1"中的类型以某种方式处理,"类别2"中的类型以不同的方式处理.

让我们进入代码.首先,我将创建六种类型.

//Category 1 Types
class Type_A{};
class Type_B{};
class Type_C{};

//Category 2 Types
class Type_D{};
class Type_E{};
class Type_F{};
Run Code Online (Sandbox Code Playgroud)

接下来,我将创建两个类型特征,以便可以在编译时发现类型的类别.

/* Build The Category 1 Type Trait */

//Type_A Type Trait
template <typename T>
struct Is_Type_A {
  static const bool value = false;
};
template <>
struct Is_Type_A<Type_A> {
  static const bool value = true;
};

//Type_B Type Trait
template <typename T>
struct Is_Type_B {
  static const bool value = false;
};
template <>
struct Is_Type_B<Type_B> {
  static const bool value = true;
};

//Type_C Type Trait
template <typename T>
struct Is_Type_C {
  static const bool value = false;
};
template <>
struct Is_Type_C<Type_C> {
  static const bool value = true;
};

//Category 1 Type Trait
template <typename T>
struct Is_Type_From_Category_1 {
  static const bool value = Is_Type_A<T>::value || Is_Type_B<T>::value || Is_Type_C<T>::value;
};

/* Build The Category 2 Type Trait */

//Type_D Type Trait
template <typename T>
struct Is_Type_D {
  static const bool value = false;
};
template <>
struct Is_Type_D<Type_D> {
  static const bool value = true;
};

//Type_E Type Trait
template <typename T>
struct Is_Type_E {
  static const bool value = false;
};
template <>
struct Is_Type_E<Type_E> {
  static const bool value = true;
};

//Type_F Type Trait
template <typename T>
struct Is_Type_F {
  static const bool value = false;
};
template <>
struct Is_Type_F<Type_F> {
  static const bool value = true;
};

//Category 1 Type Trait
template <typename T>
struct Is_Type_From_Category_2 {
  static const bool value = Is_Type_D<T>::value || Is_Type_E<T>::value || Is_Type_F<T>::value;
};
Run Code Online (Sandbox Code Playgroud)

现在我有两种类型特征来区分六种类型中的每一种类型,我想写两个函数.一个函数将接受来自类别1的所有内容,而另一个函数将接受来自类别2的所有内容.有没有办法在不创建某种调度功能的情况下执行此操作?我能找到一种只有两种功能的方法; 每个类别一个?


编辑:我试图像这样使用enable_if,但这样的尝试将导致编译器错误.

//Handle all types from Category 1
template<class T ,class = typename std::enable_if<Is_Type_From_Category_1<T>::value>::type >
void function(T t){
    //do category 1 stuff to the type
    return;
}

//Handle all types from Category 2
template<class T ,class = typename std::enable_if<Is_Type_From_Category_2<T>::value>::type >
void function(T t){
    //do category 2 stuff to the type
    return;
}
Run Code Online (Sandbox Code Playgroud)

编辑2:我已经尝试了链接中提供的代码,但这不是关于是否调用该函数的是或否决定.给定两种类型特征,我可以调用哪个函数.这将是重新定义错误.

//Handle all types from Category 2
template<class T, class dummy = typename std::enable_if< Is_Type_From_Category_1<T>::value, void>::type>
void function(T t){
    //do category 1 stuff to the type
    return;
}
//Handle all types from Category 2
template<class T, class dummy = typename std::enable_if< Is_Type_From_Category_2<T>::value, void>::type>
void function(T t){
    //do category 2 stuff to the type
    return;
}
Run Code Online (Sandbox Code Playgroud)

Sim*_*ple 11

我认为使用标签发送将比SFINAE更容易.

template<class T>
struct Category;

template<>
struct Category<Type_A> : std::integral_constant<int, 1> {};
template<>
struct Category<Type_B> : std::integral_constant<int, 1> {};
template<>
struct Category<Type_C> : std::integral_constant<int, 1> {};

template<>
struct Category<Type_D> : std::integral_constant<int, 2> {};
template<>
struct Category<Type_E> : std::integral_constant<int, 2> {};
template<>
struct Category<Type_F> : std::integral_constant<int, 2> {};

template<class T>
void foo(std::integral_constant<int, 1>, T x)
{
    // Category 1 types.
}

template<class T>
void foo(std::integral_constant<int, 2>, T x)
{
    // Category 2 types.
}

template<class T>
void foo(T x)
{
    foo(Category<T>(), x);
}
Run Code Online (Sandbox Code Playgroud)


Pot*_*ter 11

不允许两个函数签名仅由模板参数的默认值不同.如果你明确打电话function< int, void >会怎么样?

通常enable_if用作函数返回类型.

//Handle all types from Category 1
template<class T >
typename std::enable_if<Is_Type_From_Category_1<T>::value>::type
function(T t){
    //do category 1 stuff to the type
    return;
}

//Handle all types from Category 2
template<class T >
typename std::enable_if<Is_Type_From_Category_2<T>::value>::type
function(T t){
    //do category 2 stuff to the type
    return;
}
Run Code Online (Sandbox Code Playgroud)

  • @TrevorHickey`enable_if`有一个可选的返回类型的第二个模板参数,默认为`void`. (3认同)