模板参数推导顺序
Template argument deduction order
>谁能解释为什么下面的代码不能编译:
template <typename P>
struct Base
{
friend typename P::One;
friend typename P::Two;
friend typename P::Three;
};
template<typename U, typename D, typename T>
struct Derived : public Base<Derived<U,D,T>>
{
using One = U;
using Two = D;
using Three = T;
};
错误是:
..PRPmain.cpp:3:1: error: no type named 'One' in 'struct Derived<A, B, C>'
{
^
..PRPmain.cpp:3:1: error: no type named 'Two' in 'struct Derived<A, B, C>'
..PRPmain.cpp:3:1: error: no type named 'Three' in 'struct Derived<A, B, C>'
以及为什么以下代码可以完美编译:
template <typename T>
struct Sum
{
constexpr static int sze = T::uno + T::due + T::tre;
};
template<int i, int j, int k>
struct Triple : public Sum<Triple<i, j, k>>
{
constexpr static int uno = i;
constexpr static int due = j;
constexpr static int tre = k;
};
两者之间有什么区别?我认为这与模板扣除顺序有关,但我可能是错的。
我在 Win4.8 上使用 MinGW 7,并打开标志 C++11。谢谢!
您的代码中没有发生模板参数推导,因此这与推导无关。
该问题是由于尝试使用 Derived
的成员而导致的,而它是不完整的类型。
在Derived
的基类列表中发生的Base<Derived<U,D,T>>
实例化期间,编译器会立即处理友元声明,此时Derived
不完整,因此无法尝试使用其成员。
Sum
中的静态成员不会自动实例化,并且在 Triple
的声明中不需要。如果稍后使用静态成员,则Triple
是一个完整的类型,可以引用其成员。
如果您尝试在Sum
的定义中使用Sum<T>::sze
,则会收到类似的错误,因为此时T
不是完整的类型:
template <typename T>
struct Sum
{
constexpr static int sze = T::uno + T::due + T::tre;
char buf[sze];
};
template<int i, int j, int k>
struct Triple : public Sum<Triple<i, j, k>>
{
constexpr static int uno = i;
constexpr static int due = j;
constexpr static int tre = k;
};
Triple<1, 2, 3> t;
相关文章:
- 函数调用中参数的顺序重要吗
- C++部分概念 id:显式模板规范顺序/第一个参数的特殊状态的原因是什么?
- lambda 作为接受其他参数的参数的初始化顺序
- 运算符 new 的执行顺序和构造函数的参数
- 如何检查参数包是否具有执行顺序中的确切类型
- std::bind() 参数列表中函子的执行顺序(可能与函数参数的求值顺序无关)
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 如何实现对参数顺序不可知的std::same_as的广义形式(即对于两个以上的类型参数)
- 用作成员构造函数参数的函数的求值顺序
- C++17的可选和可变顺序函数参数
- 委派的 ctor 是否受参数计算顺序的影响?
- x64 函数调用参数推送/移动顺序 (MSVC)
- 函数参数计算顺序与 Lambda 捕获评估顺序
- 反转模板(整数)参数的顺序
- 大括号和括号之间的参数计算顺序
- 约束模板参数顺序的更简单方法
- C++ 更改基于参数设置的默认顺序
- 重载运算符以允许C++中参数的不同顺序
- 正确对齐内存模板,参数顺序不变
- 为具有默认值的非顺序参数函数创建启动器