带有默认模板参数的参数包

时间:2015-09-16 23:03:15

标签: c++ templates c++11 variadic

在此代码中,我尝试将Test从使用Arg推广到使用Args...。问题是默认模板参数。我在下面编译的内容,除非我取消注释main()中注释掉的行:

#include <iostream>
#include <type_traits>

struct A {
    void foo(int) const {}
    void foo(int, bool, char) const {}
};

template <typename...> struct voider { using type = void; };

template <typename... Ts>
using void_t = typename voider<Ts...>::type;

template <typename T, typename Arg, typename = void_t<T>>
struct Test : std::false_type {};

template <typename T, typename Arg>
struct Test<T, Arg, void_t<decltype(std::declval<T&>().foo(std::declval<Arg>()))>> :
    std::true_type {};

// Trying to generalize Test with Args... instead of Arg
template <typename T, typename, typename... Args> struct Check;

template <typename T, typename... Args>
struct Check<T, void_t<T>, Args...> : std::false_type {};

template <typename T, typename... Args>
struct Check<T, void_t<decltype(std::declval<T&>().foo(std::declval<Args>()...))>, Args...>
    : std::true_type {};

template <typename T, typename... Args>
using CheckArgs = Check<T, void_t<T>, Args...>;

int main() {
    std::cout << std::boolalpha << Test<A, int>::value << '\n';  // true
//  std::cout << CheckArgs<A, int, bool, char>::value << '\n';  // ambiguous
}

main()中的最后一行是不明确的。首先,为什么它不明确,而main()中的第一行不是?其次,如何修复代码,以便main中的最后一行编译(因为int,bool,char是A :: foo的参数,所以它应该计算为true)?

1 个答案:

答案 0 :(得分:3)

你想要

template <typename T, typename, typename... Args> 
struct Check : std::false_type {};

template <typename T, typename... Args>
struct Check<T, void_t<decltype(std::declval<T&>().foo(std::declval<Args>()...))>, Args...>
    : std::true_type {};

您希望主模板提供默认情况 - 即false,以及提供真实案例的部分特化。当你写两个部分特化时,两者都是可行的,两者之间没有排序,所以它最终变得模棱两可

这只是重新实现std::experimental::is_detected的更受约束的版本。