5

使用 clang 3.5.0 和 gcc 4.9.1 编译以下代码会在最后一条语句中产生错误。

#include <iostream>

struct Foo { Foo(int x, int y) { std::cout << "Foo(int = " << x << ", int = " << y << ")" << std::endl; } };

void bar(int x, int y) { std::cout << "bar(int = " << x << ", int = " << y << ")" << std::endl; }

int main()
{
   Foo({}, {});   // Foo(int = 0, int = 0)
   Foo({1}, {2}); // Foo(int = 1, int = 2)
   Foo({1, 2});   // Foo(int = 1, int = 2)

   bar({}, {});   // bar(int = 0, int = 0)
   bar({1}, {2}); // bar(int = 1, int = 2)
   bar({1, 2});   // error: no matching function for call to 'bar'  <<< Why? <<<
}

为什么Foo({1, 2})可以而bar({1, 2})不行?

特别是,了解基本原理会很棒。

4

2 回答 2

6

Foo({1,2})创建一个临时 Foo 对象并调用复制构造函数。

请参阅此修改后的示例,使用复制构造函数删除: http ://coliru.stacked-crooked.com/a/6cb80746a8479799

它错误:

main.cpp:6:5: note: candidate constructor has been explicitly deleted
    Foo(const Foo& f) = delete;
于 2014-11-07T16:59:42.000 回答
1

线

bar({1, 2});

实际上在bar函数中传入了一个临时对象类型

<brace-enclosed initializer list> // it's made clear in the comments that brace initializers have no type

并且无法将此临时对象转换为第一个参数的类型,即int. 因此错误

无法将参数转换<brace-enclosed initializer list>int1

void bar(int, int)
于 2014-11-07T17:02:58.027 回答