struct S{
constexpr S() {};
};
template <auto x> void f();
int main() {
S s{};
f<s>();
}首先,每个[temp.arg.nontype]/1
如果模板参数(13.2)的类型T包含占位符类型(9.2.9.6)或包含推导类类型的占位符(9.2.9.7),则该参数的类型是为本发明声明中的变量x推导的类型。 T=模板-参数; 如果模板参数声明(13.2)不允许推导参数类型,则程序格式不正确。
我们的模板参数包含占位符类型auto,因此参数的类型是为本发明的声明auto x = s;中的变量x推导的类型,参数的类型是S,而S是参数声明的允许类型,因为S是一种结构文字类型。
非类型模板参数的模板参数应该是模板参数类型的转换常量表达式(7.7)。
这意味着模板参数s应该是一个转换的常量表达式。每[expr.const]/10
类型
T的转换常量表达式是隐式转换为T类型的表达式,其中转换的表达式是常量表达式,隐式转换序列仅包含
在应用任何隐式转换之前,我不确定lvalue s是否被转换为prvalue。注意,C++14中转换的常量表达式的定义相对变化。N4140§5.19 [expr.const]/3: (重点地雷)
T类型的转换常量表达式是一个表达式,隐式转换为T类型的prvalue,其中转换的表达式是核心常量表达式,而隐式转换序列只包含。
因此,按照C++14,在对其应用任何隐式转换之前,都可以保证将转换后的表达式转换为prvalue。
我不太确定从lvalue到rvalue的转换是否应用于模板参数s。换句话说,我不确定lvalue s是否被转换为prvalue。
因此,一般来说,如果我将lvalue作为非类型模板参数的模板参数传递,那么lvalue到rvalue的转换是否应用于该lvalue?
除此之外,是s https://timsong-cpp.github.io/cppwp/n4868/expr.const#2对象
发布于 2022-09-25 16:53:19
expr.const/10的含义是,每当一个表达式出现在需要“转换为T类型的常量表达式”的上下文中时,该表达式就被“隐式转换为T类型”,并且应适用expr.const/10中的附加限制。
因此,在应用任何隐式转换之前,s不会“转换为prvalue”。相反,s被隐式转换为S类型,这种隐式转换可能涉及一些标准和/或用户定义的转换,例如从lvalue到rvalue的转换。要知道它是否存在,我们必须查看隐式转换的规则,这些规则都在conv.general中。特别是[conv.general]/6说
任何隐式转换的效果与执行相应的声明和初始化,然后使用临时变量作为转换的结果相同。如果
T是lvalue引用类型或函数类型的rvalue引用(dcl.ref),则结果是lvalue,如果T是对对象类型的rvalue引用,则为xvalue,否则为prvalue。表达式E被用作glvalue当且仅当初始化时使用它作为glvalue。
我相信这里的措辞是旧标准版本的遗物。应该说(在现代语言中),当T是一种非引用类型时,E到T的隐式转换会产生一个prvalue,该值初始化其结果对象(称为t),就像通过T t = E;进行的那样。
因此,我们考虑S t = s;,这个初始化是做什么的?它调用S的复制构造函数来初始化t;[dcl.init.general]/16.6.2.1。在此场景中不存在lvalue到rvalue的转换。(类类型的Lvalue到rvalue转换很少,但在语言中的某些地方确实发生,例如[expr.call]/12、[expr.cond]/7。如果在s上执行了lvalue到rvalue的转换,那么它也将调用复制构造函数;[conv.lval]/3.2。但在这种情况下,语言的规则不需要从lvalue到rvalue的转换。)
因此,使用s作为S类型的模板参数的模板参数的结果是生成一个prvalue,它通过调用以s作为参数的复制构造函数来初始化其结果对象。(这个特定的复制构造函数被隐式定义为不执行任何操作,因为没有子对象要复制。)
这回答了您关于是否应用lvalue到rvalue转换的问题。(您可能想知道prvalue实际上发生了什么,复制构造函数是否真的被调用了,但这是我现在不想讨论的另一个主题,因为它会使这个答案太长。)
至于s是否是常量初始化的,是的。它满足(2.1) (因为它有一个初始化程序)和(2.2),因为它的初始化的全部表达式是一个常量表达式(没有什么可以阻止它成为一个常量表达式,因为它除了调用constexpr默认构造函数之外什么也不做,它本身什么也不做)。不过,我不知道这和你的另一个问题有什么关系。
https://stackoverflow.com/questions/73837306
复制相似问题