問題描述
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.
這篇關于推導出第一個模板參數,其他模板參數默認的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!