为什么不能将圆括号正确地视为构造函数调用? [英] Why can't round bracket be correctly regarded as a constructor calling?

查看:103
本文介绍了为什么不能将圆括号正确地视为构造函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了 move 来模仿 std :: move ,并尝试使用新的结构 Foo 进行测试。但是,发生了一些错误。

I wrote a move to imitate std::move, and try to use a new struct Foo to test it. However, something wrong happened.

.\main.cpp: In function 'int main()':
.\main.cpp:46:7: error: conflicting declaration 'Foo x'
   46 |   Foo(x);
      |       ^
.\main.cpp:43:15: note: previous declaration as 'std::string x'
   43 |   std::string x = "123";
      |               ^

我将代码 Foo(x)替换为 Foo foo = Foo(x),那么一切都很好。
我正在使用 MinGW32 g ++ 9.2.0 ,通过命令 g ++ main.cpp -std = c ++ 14

I replace the code Foo(x) with Foo foo = Foo(x), then everything went just fine. I'm using MinGW32 g++ 9.2.0, compiling with command g++ main.cpp -std=c++14

更多信息,请参见下面的代码:

See the code below for more detail:

#include <iostream>

template <class T>
struct Remove_Reference {
  typedef T type;
};

template <class T>
struct Remove_Reference<T&> {
  typedef T type;
};

template <class T>
struct Remove_Reference<T&&> {
  typedef T type;
};

template <typename T>
constexpr typename Remove_Reference<T>::type&& move(T&& x) noexcept {
  return static_cast<typename Remove_Reference<T>::type&&>(x);
}

struct Foo {
  Foo() {}
  Foo(std::string&& foo) : val(foo) {
    std::cout << "rvalue reference initialize" << std::endl;
  }
  Foo(const std::string& foo) : val(::move(foo)) {
    std::cout << "const lvalue reference initialize" << std::endl;
  }
  std::string val;
};

void call(std::string&& x) {
  std::cout << "rvalue reference: " << x << std::endl;
}

void call(const std::string& x) {
  std::cout << "const lvalue reference: " << x << std::endl;
}

int main() {
  std::string x = "123";

  Foo{x};
  // Foo(x);

  Foo{::move(x)};
  Foo(::move(x));

  call(x);
  call(::move(x));

  return 0;
}


推荐答案

此语句:

Foo(x);

不是函数调用,也不是构造函数调用。这只是一个声明,说 x Foo 类型。括号在声明符 x 周围是可选的,因此等效于:

is not a function call, or a constructor call. It's just a declaration, that says x is of type Foo. The parentheses are optional around the declarator x, so it's equivalent to:

Foo x;

这当然会产生错误,因为您已经有 std :: string 名为 x ,并且您不能为同一范围内的多个实体提供相同的名称。

This of course gives an error, since you already have a std::string named x, and you can't give the same name to multiple entities in the same scope.

请注意表达式

Foo(x)

与上面的声明(带有; )不同。根据使用的上下文,该表达式可能表示不同的含义。

is different than the statement above (with the ;). This expression can mean different things depending on the context it is used in.

例如,这段代码:

Foo foo = Foo(x);

非常好。这确实从表达式 Foo(x)复制一个名为 foo 的变量的初始化,这是一个临时的 Foo 由参数 x 构造。 (这里不是特别重要,但是从c ++ 17开始,在右侧没有临时对象;该对象只是在适当的位置构造)。

is perfectly fine. This does copy initialization of a variable named foo, from the expression Foo(x), which is a temporary Foo constructed from the argument x. (It's not particularly important here, but from c++17, there's no temporary on the right hand side; the object just gets constructed in place).

这篇关于为什么不能将圆括号正确地视为构造函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆