c++ - 具有默认模板参数的参数包

标签 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 中的最后一行能够编译(它应该计算为 true,因为 int、bool、char 是 A::foo 的参数)?

最佳答案

你想要

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

您希望主模板提供默认情况 - 这是假的,而偏特化提供真实情况。当您编写两个部分特化时,两者都是可行的,并且两者之间没有顺序,因此最终会变得模棱两可

这只是重新实现了一个更受限制的 std::experimental::is_detected 版本.

关于c++ - 具有默认模板参数的参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32620155/

相关文章:

c++ - 向下转型时的 static_cast 悬挂引用

c++ - "vperm v0,v0,v0,v17"和未使用的 v0 有什么作用?

c++ - extern模板如何实际生成代码?

c++ - 将 std::less 与 nullptr 一起使用

c++ - 在 Rcpp 中返回 size_t 的包装

c++ - EOF,读取最后一行时永远循环。 C++

c++ - 将未知类型和数量的 args 和 concat 传递给 char 数组

c++ - 类标志的模板专门化

c++ - 如何只获得给定的捕获组 <regex> C++

c++ - 如何将模板大小的数组初始化转换为 constexpr 初始化?