【问题标题】:template type deduction of template parameter模板参数的模板类型推导
【发布时间】:2018-03-26 20:01:26
【问题描述】:

我知道,给定一个特定的函数参数,函数模板有自动类型推导的可能性,但是非类型模板参数也存在这种方法吗?

例子:

#include <iostream>

template<typename T, T val>
void func_a(void) {
    std::cout << val << std::endl;
}

template<typename T>
void func_b(T val) {
    std::cout << val << std::endl;
}

int main(void) {
    func_a<uint32_t, 42u>();
    //func_a<42u>();    //This line doesn't work
    func_b(42u);
    return 0;
}

所以当我调用func_a() 时,我不想每次都给出模板参数类型uint32_t。 C++17及以下有没有这样的方法?

我正在使用 g++ v.7.3 和 c++17。

【问题讨论】:

  • 首先,你必须让我相信 func_a 比 func_b 提供了一些东西,因为它应该被内联?
  • @GemTaylor - 也许func_a() 可以强加valconstexpr 值。
  • @max66 也许,但对于任何给定的输入,func_b 也可以。示例: // constexpr 函数使用递归而不是迭代 constexpr int factorial(int n) { return n

标签: c++ c++11 templates c++17 template-argument-deduction


【解决方案1】:

在 C++17 中,你可以使用auto:

template<auto val>
void func_a(void) {
    std::cout << val << std::endl;
}

int main(void) {
    func_a<42u>();
    return 0;
}

【讨论】:

    【解决方案2】:

    鉴于 C++17 解决方案的 +1,一个优于 C++11/C++14 解决方案的解决方案可以是使用宏在参数上激活 decltype()

    例如,用宏

    #define func_a_macro(val)  func_a<decltype(val), val>
    

    或更好,如 liliscent 所建议的那样,以避免引用问题

    #define func_a_macro(val) \
       func_a<std::remove_reference<decltype(val)>::type, val>
    

    你可以打电话

    func_a_macro(42u)();
    

    p.s.:我知道...我知道...宏是邪恶的...但有时很有用。

    【讨论】:

    • @liliscent - 绝对正确;谢谢;答案得到改善。
    【解决方案3】:

    没有宏的 C++14 解决方案:

    template<int N> auto Int = std::integral_constant<int, N>{};
    
    template<class T, T n>
    constexpr auto foo(std::integral_constant<T, n> x)
    {
        std::cout << x.value << std::endl;
    } 
    
    int main()
    {
        foo(Int<6>);
    }
    

    c++11:

    template<int N> using Int = std::integral_constant<int, N>;
    
    template<class T, T n>
    constexpr void foo(std::integral_constant<T, n> x)
    {
        std::cout << x.value << std::endl;
    } 
    
    int main()
    {
        foo(Int<6>());
    }
    

    【讨论】:

      猜你喜欢
      • 2020-07-09
      • 1970-01-01
      • 2018-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多