Gcc 和 clang 似乎不同意这段代码是否应该编译:
#include <type_traits>
template <typename Signature, int N = 0>
struct MyDelegate { };
template <typename D>
struct signature_traits;
template <template <typename> class Delegate, typename Signature>
struct signature_traits<Delegate<Signature>>
{
using type = Signature;
};
static_assert(std::is_same_v<
void(int, int),
signature_traits<MyDelegate<void(int, int)>>::type
>);
参见 godbolt output here and try it .我在这里支持 clang,但是 C++ 标准对此有何规定?
后续问题 - 这可以在 clang 中工作吗?
最佳答案
这是完全有效的代码,gcc 是正确的。 “特征”是 introduced in C++17 .它不是一个真正的特性,因为它是一个缺陷报告。 MyDelegate
匹配 signature_traits
的部分特化,因此应该像 gcc 一样正确地对待它。请注意,它之所以有效,是因为第二个模板参数是默认的。
clang 不编译的原因是因为那个缺陷报告有缺陷 :P。它doesn't introduce the appropriate change in partial ordering ,这不是很好,并且使之前有效的代码再次变得模棱两可。
预计很快就会修复,但与此同时,clang 决定“隐藏”标志后面的功能,-frelaxed-template-template-args。
因此,只需启用该标志进行编译,您应该没问题。
关于c++ - 使用默认的其他模板参数推导第一个模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51527014/