今天,在第一次使用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]));
但我真的很想知道它失败的原因。
答案 0 :(得分:5)
您是Most Vexing Parse规则的受害者。
编译器看到:
Stuff s(Link<Bus>((&buses)[0]));
作为名为s
的函数的函数声明,它返回Stuff
对象并请求Link
对象引用的0元素数组。
要解决此问题并告诉编译器您实际上是在尝试创建Stuff
对象,您应该使用{}
语法来避免含糊不清:
Stuff s{ Link<Bus>((&buses)[0]) };