为什么我的数组声明为引用数组

时间:2018-02-16 15:45:33

标签: c++ arrays pointers

今天,在第一次使用GCC 4.9.2编译某些代码时,我遇到了一个奇怪的错误,即数组被解释为引用数组。

我能够通过一个快速示例重现错误。为什么Link的构造函数将buses解释为Stuff的构造函数中的引用数组。

以下代码适用于MSVC10和ICC 11.1

#include <iostream>

struct Bus
{
    Bus(std::string n) : name(n) {}
    std::string name;
};

template<typename T>
class Link
{
public:
    Link(const T* i)
    {
        data = (T*)i;   
    }

    const T* get() const
    {
        return data;
    }
private:
    T* data = nullptr;  
};

class Stuff
{
public:
    Stuff(Link<Bus> l_b) : link(l_b) {}
private:
    Link<Bus> link;
};

void print(Link<Bus> l)
{
    std::cout << l.get()->name << '\n';   
}

int main(void) {
    Bus buses[4] = { Bus("0"), Bus("1"), Bus("2"), Bus("3") };

    print(Link<Bus>(&buses[0]));

    Stuff s(Link<Bus>(&buses[0]));    

    return 0;
}

但是对于GCC和Clang,这给出了一个错误:

main.cpp: In function 'int main()':

main.cpp:44:32: error: declaration of 'buses' as array of references

     Stuff s(Link<Bus>(&buses[0]));

然而,对print函数的调用按预期工作。我对构造函数失败的原因一无所知。

我找到了解决这个问题的方法,通过调用Stuff

的构造函数调用的公共汽车
Stuff s(Link<Bus>((&buses)[0]));    

但我真的很想知道它失败的原因。

Live example here

1 个答案:

答案 0 :(得分:5)

您是Most Vexing Parse规则的受害者。

编译器看到:

Stuff s(Link<Bus>((&buses)[0]));

作为名为s的函数的函数声明,它返回Stuff对象并请求Link对象引用的0元素数组。

要解决此问题并告诉编译器您实际上是在尝试创建Stuff对象,您应该使用{}语法来避免含糊不清:

Stuff s{ Link<Bus>((&buses)[0]) };