【发布时间】:2009-06-13 17:09:29
【问题描述】:
如何将此实例作为参数传递给函数?
class
{
public:
void foo();
} bar;
我必须给班级命名吗?
它是可复制的,因为我没有将班级的复制 ctor 设为私有。
那怎么可能呢?
【问题讨论】:
如何将此实例作为参数传递给函数?
class
{
public:
void foo();
} bar;
我必须给班级命名吗?
它是可复制的,因为我没有将班级的复制 ctor 设为私有。
那怎么可能呢?
【问题讨论】:
如果您明确说明您想做什么,也许会更好。为什么要创建一个未命名的类?它符合接口吗?未命名的类非常有限,它们不能用作函数的参数,它们不能用作模板类型参数...
现在,如果您正在实现一个接口,那么您可以传递对该接口的引用:
class interface {
public:
virtual void f() const = 0;
};
void function( interface const& o )
{
o.f();
}
int main()
{
class : public interface {
public:
virtual void f() const {
std::cout << "bar" << std::endl;
}
} bar;
function( bar ); // will printout "bar"
}
注意:对于所有将模板参数作为选项的答案,未命名的类不能作为模板类型参数传递。
C++ 标准。 14.3.1,第 2 段:
2 本地类型,没有类型 链接,未命名的类型或类型 由这些类型中的任何一种复合而成 不得用作 模板的模板参数 类型参数。
如果你用comeau编译器测试(链接是在线试用的)你会得到以下错误:
错误:模板参数不能 引用一个未命名的类型
附带说明一下,comeau 编译器是我所知道的最符合标准的编译器,除了是我尝试过的最有用的错误诊断工具。
注意:Comeau 和 gcc (g++ 4.0) 使用上面的代码会出错。英特尔编译器(以及来自其他人的 cmets MSVS 2008)接受使用未命名的类作为模板参数,违反标准。
【讨论】:
当你想将匿名类传递给函数时,为什么要创建它?
只需显式声明类:
class Foo {
// ...
};
void Method(Foo instance);
int main() {
Foo bar;
Method(bar);
}
第二种可能性是使用模板函数,因此编译器会推断类型(请注意,这不是标准兼容的!)
#include <iostream>
using namespace std;
template <typename T>
void SayFoo(T& arg) {
arg.Foo();
}
int main() {
class {
public:
void Foo() { cout << "Hi" << endl; }
} Bar;
Bar.Foo();
SayFoo(Bar);
return 0;
}
复制类没有问题,因为编译器自动生成了复制构造函数,您可以使用boost::typeof等工具来避免显式引用类型。
BOOST::AUTO(copy, Bar);
另一种方法是使用(相对较慢的)运行时多态性(接口/继承)。
【讨论】:
是的,您必须为类命名才能将其实例传递给函数。由于您没有提供自己的复制 ctor,编译器将生成自己的并使用它。
【讨论】:
嗯,无名阶级。
您可以将指向它的指针作为 void * 传递。
由于不能通过名称引用它,所以不能调用它的构造函数、复制构造函数或析构函数,只能调用一个实例,所以不能复制它。
编辑:您仍然可以将它传递给可以复制它的模板函数。
REEDIT:编辑错误。
【讨论】: