使用花括号初始化临时聚合对象

5

假设我有一个类:

class Aggregate {

public:

    int x;
    int y;

};

我知道如何使用花括号初始化一个对象:

Aggregate a1 = { 1500, 2900 };

但是我找不到创建临时对象并将其作为参数传递给某个方法的正确语法,例如:

void frobnicate(const Aggregate& arg) { 
    // do something
}

//...

frobnicate(Aggregate {1500, 2900}); // what should this line look like?

最简单的方法是将构造函数添加到Aggregate类中,但假设我无法访问Aggregate头文件。另一个想法是编写某种工厂方法,即
Aggregate makeAggregate(int x, int y).

我也可以创建一个对象,然后将其作为参数传递等等。

有许多解决方案,但我只是好奇是否可以使用花括号初始化来实现这个目标。


嗯...如果您没有访问头文件的权限,那么您不能假设对象可以使用花括号初始化,对吧? - unwind
3
其实,采用 makeXXX 方法并不是那么糟糕。最近的编译器能够应用 NRVO (命名返回值优化),从而产生高效的代码。当应用了 NRVO 并且函数被内联时,这将等同于使用 C++0x 的语法来实现高效。 - sellibitze
3个回答

8
使用C++0x初始化列表可以实现您想要的功能。
class Aggregate {
public:
    int x, y;
};

void frobnicate(const Aggregate& arg) {

}

int main() {
    frobnicate({1, 2});
    return 0;
}

使用-std=c++0x标志,GCC 4.4已经支持这一点。可能VS2010 CTP也支持(如果我错了请纠正我)。

对于C++98/C++03,您将不得不编写并调用构造函数。


3

1

有很多解决方案,但我只是好奇是否可以使用花括号初始化来实现这个目标。

不可能。如果您无法更改源代码,则唯一的选择是将其包装在内联函数或辅助结构中:

struct AggregateHelper
{
    Aggregate a;
    AggregateHelper(int x, int y) { a.x=x; a.y=y; }
    operator const Aggregate& () { return a; }
};

frobnicate(AggregateHelper(1500,2900));

编辑:已删除无关的构造函数解决方案。


然而,这也会改变该类型的属性,从原先的聚合类型(在这种情况下也是POD)变为非聚合类型。这可能不是预期的结果,并且需要对所有先前使用{}初始化的代码进行搜索和替换。 - Richard Corden

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