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

标签 c++ templates language-lawyer variadic-templates non-type

考虑以下结构:S是一个类模板,带有模板类型参数的可变参数包...Ts .该类包含一个嵌套的类模板 N ,它有一个模板模板参数 C . C本身使用一组具有完全类型 Ts... 的非类型模板参数的可变参数包进行模板化。 .

template <typename ...Ts>
struct S 
{
    template <template <Ts...> typename C>
    struct N 
    {
        C<42> c;
    };
};

GCC拒绝c的声明和:
error: expansion pattern '<anonymous>' contains no parameter packs
        C<42> c;
            ^
我不知道这个诊断意味着什么,我猜这是一个 GCC 错误。

Clang 接受这种结构,也接受合理的实例化,例如:
template<int> struct W {};
S<int>::N<W> w;             // ok, makes sense
当然,声明C<42> c;本身对用作参数 C 的参数的模板施加了限制。 ,即使 Ts... 也是必需的在 C只是 auto... .例如Ts... 的第一个参数必须是可以从 int 隐式转换的类型.此外,Ts... 中的其余参数,如果有,必须有默认值。
template<bool(*)()> struct X1 {};
S<int>::N<X1> x1;                  // error: value of type 'int' is not implicitly convertible to 'bool (*)()'
        
template<int, char> struct X2 {};
S<int>::N<X2> x2;                  // error: too few template arguments for class template 'X2'
有趣的是,...Ts 之间的关系似乎确实存在限制。和 Ts... .例如S 的所有指定参数现在必须是有效的非类型模板参数类型:
template<int> struct Y {};
S<int, void>::N<Y> y;       // error: a non-type template parameter cannot have type 'void' 
另一方面,Clang 也接受与 S 看似不兼容的参数的实例化。 , 和 C 的非类型模板参数:
template<int> struct Z {};
S<bool(*)(), bool>::N<Z> z;  // ok ?? But why? both number and type of 'Ts' is different 

这是一个 demo .
那么如何使用规则是什么...TsTs...在这种结构中相互约束?

我在试图理解这个问题时遇到了这个问题 question其中表明 MSVC 也不接受代码。

最佳答案

对于您的主要问题(具有依赖于外部类中的模板参数的非类型模板参数的嵌套类),这是 GCC 中的一个错误,#86883 (见 comment #3)

关于c++ - 嵌套类的模板模板参数的可变类型模板参数和非类型模板参数如何相互约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65015613/

相关文章:

c++ - 自动提升算术运算

c++ - 是否可以根据约束 "overload"别名模板?

c++ - 如何对迭代器的模板特化进行排序?

c - 分号真的是C中的一个序列点吗?

c++ - 在 MISRA C++ 2008 中,有人知道规则 5-0-3 中出现的特殊概念 Cvalue 表达式吗?

c++ - 如何从 C++ 中的大文本文件中读取部分数据

c++ - 运算符的模糊重载 "== "类型并没有真正不同

templates - 是否可以将 CSS3 框阴影内联应用于 HTML 电子邮件?

c++ - 具有部分定义类的模板化 constexpr 函数调用会更改后续结果

c++ - 模板化友元声明在 g++ 5.4.0 下不起作用——编译器错误或错误代码?