“对象”;不是一个结构或联合体”;如果将临时文件传递给构造函数 我以前没有见过C++的这种奇怪的现象,它给我造成了一些混淆。

“对象”;不是一个结构或联合体”;如果将临时文件传递给构造函数 我以前没有见过C++的这种奇怪的现象,它给我造成了一些混淆。,c++,C++,我有以下课程: class KeyValuesParser { public: explicit KeyValuesParser(const QByteArray &input); QJsonDocument toJsonDocument(QString* errorString = nullptr); // ... }; 我试着在Qt单元测试中这样使用它: const char* testData = "..."; KeyValuesParser parse

我有以下课程:

class KeyValuesParser
{
public:
    explicit KeyValuesParser(const QByteArray &input);
    QJsonDocument toJsonDocument(QString* errorString = nullptr);

    // ...
};
我试着在Qt单元测试中这样使用它:

const char* testData = "...";
KeyValuesParser parser(QByteArray(testData));
QJsonDocument doc = parser.toJsonDocument();
这会产生以下编译错误:

Member reference base type 'KeyValuesParser(QByteArray)' is not a structure or union.
但是,如果我在堆栈上创建字节数组,然后将其传入,而不是传入临时数组,则一切都可以正常编译:

const char* testData = "...";
QByteArray testByteArray(testData)
KeyValuesParser parser(testByteArray);
QJsonDocument doc = parser.toJsonDocument();
我认为这可能是一些奇怪的黑魔法,需要
显式
关键字(这就是我添加它的原因),但这没有任何区别。有人能解释一下这是怎么回事吗

编辑:我被指的另一个问题是重复的,我认为几乎是重复的,但是这个问题上有一些最令人烦恼的语法混乱,我认为值得额外讨论。

这行

KeyValuesParser parser(QByteArray(testData));
不是对象声明。它是一个函数声明,该函数返回一个KeyValuesParser并接受一个QByteArray参数


这叫做(链接到维基百科,你也会在StackOverflow上找到很多)。为了保持简短,当有疑问时,C++标准更喜欢函数声明,因为./P>

NB。这是乔纳斯在我身边回答的补充

<>你想做的是把rValk绑定到LValk引用,这在C++标准中是不允许的。在第二个示例中,通过引用正确地传递左值,这就是它工作的原因

绑定值与LValk引用是VisualC++扩展,G++根本不能做,CLAN可以用-FMS扩展< /P> < P>来做,这是一个“最令人烦恼的解析”问题。c++11为我们带来了两种解决方案:自动和支架初始化:

// use auto to turn the expression unambiguously into an rvalue
// without having to mention the class name twice
int main()
{
  const char* testData = "...";
  auto parser = KeyValuesParser(QByteArray(testData));
  auto doc = QJsonDocument(parser.toJsonDocument());
}


// or use brace initialisation to avoid the parse ambiguity 
//    
int main2()
{
  const char* testData = "...";
  KeyValuesParser parser{ QByteArray(testData) };
  QJsonDocument doc{ parser.toJsonDocument() };
}

// another solution:

const char* testData = "...";
auto doc = QJsonDocument(KeyValuesParser(QByteArray(testData)).toJsonDocument());

// yet another

const char* testData = "...";
auto doc = QJsonDocument { KeyValuesParser { QByteArray(testData) }.toJsonDocument() };

@KenY-N的可能副本我也觉得一定有副本,但你建议的副本不是那个。在建议的副本中,嵌套参数是一个值,而不是一个名称,这可以防止发生最麻烦的解析。不过,最麻烦的解析是这里的直接问题。如果没有人告诉我其他的,我会认为
QByteArray(testData)
参数足以排除函数声明的MVP语句,因为它是实际对象而不是类型名。我不认为可以通过将临时值传递给一个不可见参数来声明函数?我稍后回到这个文件,就是这样-构造函数参数作为
常量QByteArray&
存储在类中,因此传递临时值不起作用。我认为是这个错误让我困惑,因为我本以为它会挑出特定的成员初始化,而不是说整个对象不合适。