C++ 如何在编译时评估基元模板与类模板?

C++ 如何在编译时评估基元模板与类模板?,c++,class,c++11,templates,primitive-types,C++,Class,C++11,Templates,Primitive Types,当我们这样做的时候 template <typename T> void foo(T x) { if (is_fundamental<T>::value) { ... } else { ... } } 一个解决方案是重载所有可能的基元类型,但这并不是一个令人满意的解决方案,因为它需要多次复制基元类型的代码。没有办法用一个类型名引用所有的原语吗?那么标签调度呢 template <typename T> v

当我们这样做的时候

template <typename T>
void foo(T x)
{
   if (is_fundamental<T>::value)
   {
       ...
   } else
   {
     ...
   }
}

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

那么标签调度呢

template <typename T>
void fooHelper (T t, std::true_type const &)
 { /* true case */ }

template <typename T>
void fooHelper (T t, std::false_type const &)
 { /* false case */ }

template <typename T>
void foo (T t)
 { fooHelper(t, std::is_fundamental<T>{}); }
在C++17中,if constexpr语句在编译时计算条件并丢弃未选择的分支:

if constexpr(std::is_fundamental_v<T>) {
    // do something with x
} else {
    // do something else with x
}
一种老式的方法是使用标记分派:

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>{});
}

您也可以使用部分专用的helper结构,但它的代码更多。

如果不重复,则相关@StoryTeller感谢链接。链接的解决方案意味着重载每个基元类型的函数,对吗?这不太理想。没有办法用一个typename引用所有的原语吗?
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>{});
}