【问题标题】:Dependent type automatic deduction受抚养人类型自动扣除
【发布时间】:2017-06-07 14:13:32
【问题描述】:

是否可以这样做:

template<class T, T type>
constexpr auto f(/* type used in some way... */) // -> decltype (etc. in case of C++11)
  {
  return std::integral_constant<T,t>{};
  }

constexpr auto z = f(3); // z is deduced as an integral_constant<int,3>;

使用运行时值肯定是不可能的,但在这种情况下 3 是编译时值。也许有人知道一些我不知道的技巧......

[编辑] constexpr auto z2 = f(); // 这样也可以

我只是想避免重复输入..

【问题讨论】:

    标签: c++ c++11 templates template-meta-programming type-deduction


    【解决方案1】:

    您可以在 C++17 中使用auto 模板参数:

    template <auto T>
    constexpr auto f()
    {
        return std::integral_constant<decltype(T), T>{};
    }
    

    用法:

    f<3>(); // integral_constant<int, 3>
    

    或者,您需要以编译时友好的方式包装您的值:

    template <int X>
    struct int_ 
    { 
        using type = int;
        static constexpr value = X; 
    };
    
    template <typename T>
    constexpr auto f(T)
    {
        return std::integral_constant<typename T::type, T::value>{};
    }
    

    用法:

    f(int_<3>{});
    

    【讨论】:

    • 感谢您的回复。我忘了提到这是一个 C++11 问题。这是应该使用 C++17 的原因之一,因为该代码将是理想的解决方案!不幸的是,第二种方法不适合我想要实现的目标。我想避免创建像 int_ 这样的结构
    【解决方案2】:

    由于c++11你可以声明自己的文字(我在这里使用std::index_sequence,它是c++14,但你可以很容易地找到上述c++11的实现):

    #include <utility> // for std::index_sequence and std::size_t
    
    constexpr std::size_t ipow(std::size_t base, int exp, std::size_t result = 1) {
      return exp < 1 ? result : ipow(base*base, exp/2, (exp % 2) ? result*base : result);
    }
    
    constexpr std::size_t vdot(std::index_sequence<>, std::index_sequence<>) {
        return 0;
    }
    
    template <std::size_t C, std::size_t... Cs, std::size_t I, std::size_t... Is>
    constexpr std::size_t vdot(std::index_sequence<C, Cs...>, std::index_sequence<I, Is...>) {
        return C*ipow(10, I) + vdot(std::index_sequence<Cs...>{}, std::index_sequence<Is...>{});
    }
    
    template <char... Cs>
    std::integral_constant<std::size_t, vdot(std::index_sequence<static_cast<std::size_t>(Cs - '0')...>{}, std::make_index_sequence<sizeof...(Cs)>{})> operator ""_ic() {
        return {};
    }
    
    int main() {
       auto ic = 3_ic;
       static_cast<void>(ic);
    }
    

    [live demo]

    【讨论】:

    • 我会尝试更深入地了解您的解决方案.. 但我认为这不会满足我的需要:integral_constant 例如
    【解决方案3】:

    在 C++11 和 C++14 中这是不可能的

    §14.8.2.5 [temp.deduct.type] 13 和 14

    不能从非类型的类型推导出模板类型参数 模板参数。 [示例:

    template<class T, T i> void f(double a[10][i]); 
    int v[10][20]; 
    f(v); // error: argument for template-parameter T cannot be deduced 
    

    ——结束示例]

    所以你不得不指定一个类型。例如f&lt;int, 3&gt;(/*...*/)

    我非常感谢@Barry 教我这个in his answer to my last question

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-09
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多