用于数字类型的c++模板

C++ template for numeric types

本文关键字:c++ 模板 类型 数字 用于      更新时间:2023-10-16

我想有一个模板来选择数字类型,但我也想有一个全局类型模板太。我试着用这个方法解决这个问题,但是没有用:

template<typename T, typename ... Types>
void myFct(T arg1, Types ... rest) { /*do stuff*/ }
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type, 
                     typename ... Types>
void myFct(T arg1, Types ... rest) { /* do stuff */ }

,因为现在我有两个具有相同头文件的函数。正确的做法是:

template<typename T, typename ... Types>
void myFct(T arg1, Types ... rest) 
{ 
    if (isNumeric(T))
        doNumericStuff();
    else
        doStuff();
}

可能有更好的方法来做到这一点,但对我来说最简单的方法是将enable_if粘贴到返回类型上:

template<typename T, typename ... Types>
typename std::enable_if<
    std::is_arithmetic<T>::value
>::type
myFct(T arg1, Types ... rest) { /*do numeric stuff*/ }
template<typename T, typename ... Types>
typename std::enable_if<
    !std::is_arithmetic<T>::value
>::type
myFct(T arg1, Types ... rest) { /*do non-numeric stuff*/ }

一旦你有两个以上互斥的选项,这将变得非常笨拙,但这绝对是可行的。

您可以在这里使用标签调度,并重载实现函数,因为您的"do stuff"似乎一次只关注一个对象。

template <typename T>
void do_stuff(T arg, std::true_type) {
  std::cout << "numbern";
}
template <typename T>
void do_stuff(T arg, std::false_type) {
  std::cout << "not-numbern";
}
void myFct() { }
template<typename T, typename... Ts>
void myFct(T arg1, Ts... rest) {
    // is_arithmetic will derive either true_type or false_type
    do_stuff(arg1, std::is_arithmetic<T>{});
    myFct(rest...); // recurse
}

这是获得类似"static if"的典型模式

如果我用myFct(1, std::string{}, 2.0);调用它,我得到输出

number
not-number
number