推导出第一个模板参数,其他模板参数默认
Gcc 和 clang 似乎不同意这段代码是否应该编译:
Gcc and clang seem to disagree on whether this code should compile or not:
#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 输出并尝试一下.我在这里支持 clang,但 C++ 标准对此有何评论?
See godbolt output here and try it. I'm siding with clang here, but what does the C++ standard say about this?
一个后续问题 - 这可以在 clang 中工作吗?
A follow-up question - can this be made to work in clang?
推荐答案
这是完全有效的代码,gcc 是正确的.功能"是 在 C++17 中引入.这并不是真正的功能,因为它是一份缺陷报告.MyDelegate
匹配 signature_traits
的部分特化,所以它应该像 gcc 一样正确.请注意,它有效,因为第二个模板参数是默认的.
This is perfectly valid code, and gcc is right. The "feature" was introduced in C++17. It's not really a feature because it is a defect report. MyDelegate
matches the partial specialization of signature_traits
, and so it should be taken as gcc correctly does. Note that it works because the second template parameter is defaulted.
clang 不编译它的原因是因为那个缺陷报告有一个缺陷:P.它没有在偏序中引入适当的变化,这是不太好,使之前的有效代码再次变得模棱两可.
The reason why clang doesn't compile it is because that defect report has a defect :P. It doesn't introduce the appropriate change in partial ordering, which is not really nice and makes previousy valid code ambiguous again.
预计很快就会修复,但与此同时,clang 决定将功能隐藏"在一个标志后面,-frelaxed-template-template-args.
It is expected to be fixed soon, but in the meanwhile, clang decided to "hide" the feature behind a flag, -frelaxed-template-template-args.
所以,只要在启用该标志的情况下编译就可以了.
So, just compile with that flag enabled and you should be fine.
相关文章