c++ - 使用默认的其他模板参数推导第一个模板参数

标签 c++ templates language-lawyer template-meta-programming c++17

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/

相关文章:

c++ - 嵌套类的模板模板参数的可变类型模板参数和非类型模板参数如何相互约束?

c++ - 如何在 Intel 语法中使用 clang 生成汇编代码?

c++ - 在 C++ 中, `var << ifstream` 与 `ifstream >> var` 相同吗?

c++ - 如何将重复的字段部分合并到消息中?

c++ - 为什么友元函数无法访问类的私有(private)成员

c++ - 有没有一种方法可以基于当前类中的可用重载来进行 SFINAE?

javascript - getOwnPropertyNames 在 Firefox 上忽略 __proto__

c++ - 如果不为空,则为指针赋值

C++ 模板和继承

c++ - std::tuple sizeof,是不是错过了优化?