标签: most-vexing-parse

带空括号的默认构造函数

有没有什么好的理由在C++中调用默认构造函数时,一组空的圆括号(括号)无效?

MyObject  object;  // ok - default ctor
MyObject  object(blah); // ok

MyObject  object();  // error
Run Code Online (Sandbox Code Playgroud)

我似乎每次都自动输入"()".是不是有一个很好的理由不允许这样做?

c++ constructor c++-faq default-constructor most-vexing-parse

192
推荐指数
8
解决办法
3万
查看次数

为什么C++允许我们在声明变量时用括号括起变量名?

例如,声明如下:

int (x) = 0;
Run Code Online (Sandbox Code Playgroud)

甚至是:

int (((x))) = 0;
Run Code Online (Sandbox Code Playgroud)

我偶然发现了这一点,因为在我的代码中我碰巧有一个类似于下面的片段:

struct B
{
};

struct C
{
  C (B *) {}
  void f () {};
};

int main()
{
  B *y;
  C (y);
}
Run Code Online (Sandbox Code Playgroud)

显然,我想构造一个对象C,然后在它的析构函数中做一些有用的东西.但是,当它发生时,编译器将其C (y);视为y带有类型的变量声明,C因此它会输出有关y重新定义的错误.有趣的是,如果我把它写成C (y).f ()或类似的东西C (static_cast<B*> (y))将按预期编译.当然,最好的现代解决方法是{}在构造函数调用中使用.

因此,当我在那之后发现,可以声明变量之类的int (x) = 0;甚至是,int (((x))) = 0;但我从未见过任何人实际使用这样的声明.所以我很感兴趣 - 这种可能性的目的是什么,因为现在我看到它只创造了类似于臭名昭着的"最令人烦恼的解析"的情况,并没有添加任何有用的东西?

c++ most-vexing-parse

81
推荐指数
2
解决办法
4725
查看次数

我不明白为什么会编译

我当然错过了一些东西,但我不明白为什么会编译(同时使用 g++ 和 clang++):

struct A
{
};
struct B
{
};

int main()
{
  A a(B);
}
Run Code Online (Sandbox Code Playgroud)

首先,B是一种类型……而不是值。我应该如何解释这段代码?

c++ syntax declaration most-vexing-parse

81
推荐指数
3
解决办法
7076
查看次数

为什么这会调用默认构造函数?

struct X
{
    X()    { std::cout << "X()\n";    }
    X(int) { std::cout << "X(int)\n"; }
};

const int answer = 42;

int main()
{
    X(answer);
}
Run Code Online (Sandbox Code Playgroud)

我本来希望这打印

  • X(int),因为X(answer);可以解释为铸件从intX,或
  • 什么都没有,因为X(answer);可以解释为变量的声明.

但是,它打印X(),我不知道为什么X(answer);会调用默认构造函数.

奖励积分:我需要更改什么才能获得临时而非变量声明?

c++ syntax most-vexing-parse

80
推荐指数
3
解决办法
2455
查看次数

如果没有默认构造函数,为什么不编译?

我可以做这个:

#include <iostream>

int counter;

int main()
{
    struct Boo
    {
        Boo(int num)
        {
            ++counter;
            if (rand() % num < 7) Boo(8);
        }
    };

    Boo(8);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这将编译正常,我的计数器结果是21.但是,当我尝试创建Boo传递构造函数参数而不是整数文字的对象时,我得到一个编译错误:

#include <iostream>

int counter;

int main()
{
    struct Boo
    {
        Boo(int num)
        {
            ++counter;
            if (rand() % num < 7) Boo(num); // No default constructor 
                                            // exists for Boo
        }
    };

    Boo(8);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何在第二个示例中调用默认构造函数,而不是在第一个示例中调用?这是我在Visual Studio 2017上遇到的错误.

在线C++编译器onlineGDB我得到错误:

error: no matching function for call to ‘main()::Boo::Boo()’ …
Run Code Online (Sandbox Code Playgroud)

c++ constructor scope default-constructor most-vexing-parse

70
推荐指数
2
解决办法
5193
查看次数

Visual Studio C++编译器奇怪的行为

我只是想知道为什么这小段代码在Visual Studio中正确编译(并且没有警告).也许结果与GCCClang相同,但不幸的是我现在无法测试它们.

struct T {
    int t;
    T() : t(0) {}
};

int main() {
    T(i_do_not_exist);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ most-vexing-parse visual-studio-2012

36
推荐指数
2
解决办法
1158
查看次数

当有额外的括号时,在临时对象上调用用户定义的operator +时出错

如果我有一个用户定义operator+()的:

    class A
    {
    public:
        A operator+(A)
        {
            return A();
        }
    };
Run Code Online (Sandbox Code Playgroud)

然后以下按预期工作:

    A a = A() + A();
Run Code Online (Sandbox Code Playgroud)

但g ++ - 4.7给出了以下错误消息:

    A a = (A()) + A();
Run Code Online (Sandbox Code Playgroud)

特别是错误消息是error: no match for ‘operator+’ in ‘+A()’.
看起来(A())在表达式中被忽略了.

我的问题是:A a = (A()) + A();应该编译,如果没有,为什么不呢?

注意:当我这样#define X (Identity())做时,这发生在我身上然后尝试了X + X.

c++ operator-overloading most-vexing-parse

32
推荐指数
1
解决办法
300
查看次数

最烦解析更烦

在下面的代码中

#include <map>
#include <string>

struct P2d {
    double x, y;
    P2d(double x, double y) : x(x), y(y) {}
};

double bar() {
    std::map<std::string, int> m;
    //P2d lp = P2d(double(m["x"]), double(m["y"])); // this works
    P2d lp(double(m["x"]), double(m["y"]));
    return lp.x;
}
Run Code Online (Sandbox Code Playgroud)

我测试的所有编译器都同意代码(未注释版本)无效,但我不明白为什么定义

 P2d lp(<double>, <double>);
Run Code Online (Sandbox Code Playgroud)

我使用的是不可接受的。

我记得规则是“如果它既可以是函数声明又可以是定义,那么它就是声明”,但我希望如果它不能是声明,那么它应该被解释为定义而不是给出错误。

我错过了什么?

c++ most-vexing-parse

29
推荐指数
1
解决办法
892
查看次数

最烦恼的解析

我从这里得到了代码.

class Timer {
 public:
  Timer();
};

class TimeKeeper {
 public:
  TimeKeeper(const Timer& t);

  int get_time()
  {
      return 1;
  }
};

int main() {
  TimeKeeper time_keeper(Timer());
  return time_keeper.get_time();
}
Run Code Online (Sandbox Code Playgroud)

从它的外观来看,由于该行应该会出现编译错误:

TimeKeeper time_keeper(Timer());
Run Code Online (Sandbox Code Playgroud)

但只有在return time_keeper.get_time();存在的情况下才会发生 .

为什么这条线甚至很重要,编译器会发现time_keeper(Timer() )构造上的含糊不清.

c++ most-vexing-parse

27
推荐指数
1
解决办法
2436
查看次数

g ++ rejects,clang ++接受:foo(x)("bar")("baz");

前几天有人曾过为什么有些东西会与clang编译,而不是与gcc编译.我直观地理解了发生了什么,并且能够帮助这个人,但它让我想知道 - 根据标准,哪个编译器是正确的?这是代码的简化版本:

#include <iostream>
#include <string>

class foo
{
public:
    foo(const std::string& x):
        name(x)
    { }
    foo& operator()(const std::string& x)
    {
        std::cout << name << ": " << x << std::endl;
        return (*this);
    }
    std::string name;
};

int main()
{
    std::string x = "foo";
    foo(x)("bar")("baz");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用clang ++可以很好地编译,但是g ++会出现以下错误:

runme.cpp: In function ‘int main()’:
runme.cpp:21:11: error: conflicting declaration ‘foo x’
    foo(x)("bar")("baz");
        ^
runme.cpp:20:17: error: ‘x’ has a previous declaration as ‘std::string x’
    std::string x = …
Run Code Online (Sandbox Code Playgroud)

c++ syntax g++ most-vexing-parse clang++

25
推荐指数
2
解决办法
514
查看次数