索引属性如何返回引用?

时间:2013-11-01 19:23:27

标签: c++ visual-c++

以下代码无法使用Visual Studio 2012进行编译,但错误: C2234:'Foo':引用数组是非法的

struct MyClass
{
  int m_var;
  __declspec(property(get=GetFoo)) int& Foo[];   // < C2234
  int& GetFoo(int) { return m_var; }
};

我想知道为什么会这样。

是的,标准禁止引用数组。 但是,Foo []不是数组,而是成员函数GetFoo()的符号链接。 它的行为就好像Foo是一个带有重载索引操作符的类。 另一方面,以下代码完全合法,尽管它在技术上等同于前面的代码段:

struct FooClass
{
    int m_var;
    int& operator[](int) { return m_var; }
};

struct MyClass
{
    FooClass Foo;
};

那么为什么发出错误C2234?这是编译器设计错误吗?

BTW:实际情况比较复杂,所以没有必要告诉我将成员转交给成员可能是个坏主意。

1 个答案:

答案 0 :(得分:2)

我对此错误并不感到惊讶,因为int& Foo[];是int引用数组的声明。 __declspec(property)的语法指定此关键字后面的内容是声明符:__declspec(property) documentation。因此,您应该将__declspec(property)右侧的文本视为声明而不是某些特殊的符号链接。

正如您和您的编译器所指出的那样,禁止声明引用数组。 __declspec(property)也不例外。

您可以使用此替代方法:

struct MyClass
{
    int m_var;
    __declspec(property(get=GetFoo,put=SetFoo)) int Foo[];   // < C2234
    int& GetFoo(int) { return m_var; }
    void SetFoo(int, int v) {m_var = v;}
};

int main()
{ 
    MyClass test;
    test.Foo[0] = 5;

    std::cout << test.Foo[0];

    return 0;
}

如果我是你,我会坚持使用标准C ++的好'运算符[]。 __declspec语法特定于Microsoft的Visual Studio。