【问题标题】:How to evaluate Primitive vs Class templates at compilation time?如何在编译时评估 Primitive vs Class 模板?
【发布时间】:2018-06-23 00:40:48
【问题描述】:

当我们这样做时......

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

我认为if 语句(以及is_fundamental&lt;T&gt;::value)是在运行时评估的,对吗?

如果是,有没有办法在编译时进行此评估?我想要类似的东西......

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


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

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

【问题讨论】:

标签: c++ class c++11 templates primitive-types


【解决方案1】:

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

您也可以使用部分专用的帮助器结构,但它需要更多代码。

【讨论】:

    【解决方案2】:

    标签调度呢?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-04
      • 2011-09-27
      • 1970-01-01
      • 2020-08-22
      • 1970-01-01
      • 2015-03-21
      • 2012-02-01
      • 1970-01-01
      相关资源
      最近更新 更多