数字类型的 C++ 模板

问题描述 投票:0回答:2

我想要一个用于选择数字类型的模板,但我也想要一个全局类型模板。我尝试应用this问题的解决方案,但它不起作用:

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();
}
c++ templates c++11
2个回答
6
投票

可能有更好的方法来做到这一点,但对我来说最简单的方法是将

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*/ }

一旦你有不止两个互斥的选项,这就会变得非常笨拙,但这肯定会起作用。


5
投票

C++17 更新

if constexpr
丢弃未使用的分支,因此这更容易(实时链接):

void myFct() { }

template<typename T, typename... Ts>
void myFct(T arg1, Ts... rest) {
    if constexpr (std::is_arithmetic<T>{}) {
        std::cout << "squared: " << arg1*arg1 << '\n';
    } else {
        std::cout << "not-number\n";
    }
    myFct(rest...); // recurse
}

您可以在此处使用标签分派,并重载实现函数,因为您的“做的事情”似乎一次只涉及一个对象。

template <typename T>
void do_stuff(T arg, std::true_type) {
  std::cout << "number\n";
}

template <typename T>
void do_stuff(T arg, std::false_type) {
  std::cout << "not-number\n";
}

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
}

这是获得“静态 if”之类的典型模式

如果我用

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

number
not-number
number
© www.soinside.com 2019 - 2024. All rights reserved.