VC 错误,带有声明和通用引用或未定义的行为
VC++ Bug with Decltype and Universal Reference or Undefined Behavior?
我有此代码:
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
T f2(T&&t) {
return t;
}
int rr(int i) {
return 40*i;
}
int main()
{
cout << is_function< remove_reference<decltype(f2(rr))>::type>::value << endl;
}
使用VC 2015编译时,我得到了此错误:
error C2893: Failed to specialize function template 'T f2(T &&)'
主要问题是在表达式f2(rr)
上使用decltype()
。请注意,f2
的参数为T&&
。这是Scott Meyers:Universal Reference的通用参考。我期望f2(rr)
会产生一种表达式,其类型是函数参考。在GCC中,它正常运行并返回真实,因此确认f2(rr)
是函数参考。
这仅仅是一个带有VC 2015的错误,而不是与函数名称一起使用的Univeral引用时不确定的行为?
编辑:这在VC 2015中正确起作用:
int main()
{
cout << f2(rr)(10) <<endl;
}
结果:
400
通用引用是可以将模板参数推导为参考类型的特殊上下文。假设我们有
template <typename T> auto f(T &&) -> T;
int i;
int g(int);
f(i)
将 T
推论为 int &
,以形成 auto f<int &>(int &) -> int &
。
f(std::move(i))
将T
推论为int
以形式auto f<int>(int &&) -> int
。
发生这种情况的规则以:
14.8.2.1从函数调用[temp.deduct.call]
从函数调用[temp.deduct.call]推论模板参数3 [...]如果
P
是对CV UNQUALIFIED模板参数的RVALUE引用,并且该参数为lvalue,则" type" type'lvalue引用了A
&quot&quord&quort'用于代替A
进行类型扣除。[...]
问题是,当调用f(g)
时,g
是lvalue吗?
提出问题甚至有意义吗?如果T
是函数类型,则T &
和T &&
都可以使用std::move
来创建对命名函数的引用。功能不存在lvalue/rvalue区别。
任意地,C 标准说是的,g
是一个LVALUE。功能类型的表达式永远不会是RVALUE(无论是XVALUES还是PRVALUES)。可以产生对功能类型的rvalue引用的类型,但是即使到那时,它们所形成的表达式也是lvalues。标准中其他地方还有更多的明确陈述,但它们源于:
3.10 lvalues and rvalues [basic.lval]
(1.1) - lvalue [...]指定函数或对象。[...]
(1.2) - xvalue [...]也指一个对象,[...]
(1.4) - rvalue [...]是xvalue,临时对象(12.2)或subobject,或与对象无关的值。
(注意:g
都不是"值得",因此上一部分不适用。" value"在[basic..types] p4中定义,并且适用于琐碎的可复制类型,哪些功能类型不是。)
由于g
是LVALUE,因此T
应将其推定为int(&)(int)
,这是VC 中的错误。
- 编译C++时未定义的引用
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 未定义的引用在哪里
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 未定义的引用 .. 使用 OpenCV 编译 C++ 代码时,从命令行
- 对 Scalar ::Scalar() 的未定义引用
- 已定义函数时出现 G++ "未定义的引用"错误
- 链接 cmake 时出现未定义的引用错误
- 对复制 CTOR 和 CTOR 的未定义引用
- 错误:未定义对'oboe::AudioStreamBuilder::openStream(oboe::AudioStream**)'的引用
- 右值引用未定义的行为
- 对"vtable for DigitalClock"的未定义引用 - 未定义对"DigitalClock::staticMetaObject"的引用 - Qt
- 函数类型到函数类型的引用:未定义的引用
- avcodec_alloc_context引用未定义,但ffmpeg链接顺序正确
- 从c++调用Fortran子程序,链接时引用未定义
- 枚举引用未定义,但位于包含的头文件中