通过引用传递匿名变量

6

标准的C++类型,如int或char,具有构造函数,因此您可以使用以下表达式:

int a = int(67); // create anonymous variable and assing it to variable a
int b(13);       // initialize variable b
int(77);         // create anonymous variable

用户自定义类型(结构体或类)也能够做到同样的事情:

struct STRUCT
{
  STRUCT(int a){}
};

STRUCT c = STRUCT(67);
STRUCT d(13);
STRUCT(77);

问题是:为什么我们可以通过引用匿名结构体或类的实例进行传递,但不能传递标准类型?
struct STRUCT
{
  STRUCT(int a){}
};

void func1(int& i){}
void func2(STRUCT& s){}
void func3(int i){}
void func4(STRUCT s){}

void main()
{
  //func1(int(56));  // ERROR: C2664
  func2(STRUCT(65)); // OK: anonymous object is created then assigned to a reference
  func3(int(46));    // OK: anonymous int is created then assigned to a parameter
  func4(STRUCT(12)); // OK: anonymous object is created then assigned to a parameter
}

5
你的 func2 行不应该编译(原因与第一行相同)。 - Mat
void main() 是非标准的写法。 - n. m.
1
或许我们需要说这些是非标准的,否则会误导人。C++/CLI 是非标准的。void main 是错误的。 - Konrad Rudolph
@n.m. 只是说明了有关代码在 C++ 标准符合性方面的测试结果非常好 :) - BЈовић
谢谢!但是void main()的意思只是程序不会向调用环境返回值,而是作为一个过程执行。 - Ivars
显示剩余2条评论
3个回答

7
如果你的编译器允许这样做,那么它就不是一个符合标准的C++编译器。你不能将临时rvalue绑定到非const lvalue引用。这是规则。无论是clang还是gcc都无法为func2(STRUCT(65));编译该代码。
相反,你有以下替代方案:
void func1(int&& i){}

void func1(const int& i){}

从C++03继承下来的问题:对于非const类型的(左值)引用(int &i),假设可以更改参数,然后传递诸如56之类的临时对象是不合逻辑的,因为它是不可更改的。对于const类型的引用(const int &i),应该只能观察其作为只读的值,因此传递临时值例如52是合法的。
在C++11中,您可以通过&&引用非const临时对象。

5

看起来您正在使用存在此类错误的MS VC ++编译器。:) 您需要将临时对象绑定到const引用上。例如,您可以这样写:

const int &ri = 10;

但你可能不会写

(涉及IT技术)
int &ri = 10;

同样适用于用户自定义类型。
const STRUCT &rs = STRUCT( 10 );

STRUCT &rs = STRUCT( 10 ); // the compiler shall issue an error.

0
在C++中,匿名临时对象始终是右值。要接受右值作为参数,您可以:
1).void foo1(TYPE); //按值传递 2).void foo2(const TYPE &); //通过const引用传递 3).void foo3(TYPE &&); //在C++11中,通过右值引用传递
您的“func3”和“func4”接受按值传递的参数,这是可以的。 但是,“func1”和“func2”只能接受通过左值引用传递的参数。因此,传递匿名参数是错误的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接