模板参数的模板类型推导

template type deduction of template parameter

我知道,在给定特定函数参数的情况下,可以自动推导函数模板的类型,但是对于非类型模板参数是否也存在这样的方法?

示例:

#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;
}

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

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

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

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

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

给定 C++17 解决方案的 +1,better-than-nothing 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.: 我知道...我知道...宏是邪恶的提炼...但有时很有用。

没有宏的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>());
}