如何在编译时评估Primitive vs Class模板?

Rem*_*i.b 0 c++ templates class primitive-types c++11

当我们做...

template <typename T>
void foo(T x)
{
   if (is_fundamental<T>::value)
   {
       ...
   } else
   {
     ...
   }
}
Run Code Online (Sandbox Code Playgroud)

我认为if声明(以及is_fundamental<T>::value)在运行时进行评估,是吗?

如果是,是否有办法在编译时进行此评估?我希望有类似......

template <primitive_typename T>
void foo(T x)
{
   ...
}


template <noPrimitive_typename T>
void foo(T x)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

一种解决方案是重载每种可能的原始类型,但它并不是一个令人满意的解决方案,因为它需要多次复制基本类型的代码.有没有办法用一个类型名称来引用所有原语?

Bri*_*ian 8

在C++ 17中,if constexpr语句在编译时评估条件并丢弃未选择的分支:

if constexpr(std::is_fundamental_v<T>) {
    // do something with x
} else {
    // do something else with x
}
Run Code Online (Sandbox Code Playgroud)

一种老式的方法是使用标签发送:

template <typename FundamentalType>
void foo_helper(FundamentalType x, std::true_type);

template <typename NonFundamentalType>
void foo_helper(NonFundamentalType x, std::false_type);

template <typename T>
void foo(T x) {
    foo_helper(x, std::is_fundamental<T>{});
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用部分专用的辅助结构,但它的代码更多.