很奇怪的过载失败

时间:2018-06-03 16:14:09

标签: c++

我遇到了一个非常奇怪的过载故障。我能够孤立这个问题,但我不能为它的生活弄清楚出了什么问题。

代码如下

#include <vector>
#include <iostream>

template<class X>
class Foo
{
public:
  Foo(const std::initializer_list<X> &A){}
  Foo(size_t n){}
};

class Bar
{
public:
  Bar() = default;
  Bar(const Foo<size_t> &A, bool a=true, bool b=true){};
};

int main()
{
  Bar A({1,2});
}

中编译结果
$ clang++ -std=c++14 so.cpp

so.cpp:21:11: error: call to constructor of 'Bar' is ambiguous
      Bar A({1,2});
          ^ ~~~~~
so.cpp:12:11: note: candidate is the implicit move constructor
    class Bar
          ^
so.cpp:12:11: note: candidate is the implicit copy constructor
so.cpp:16:7: note: candidate constructor
      Bar(const Foo<size_t> &A, bool a=true, bool b=true){};
      ^
1 error generated.

解决问题的两件事是:

  • 删除Foo(size_t n)
  • 将构造函数更改为Bar(const Foo<size_t> &A)

显然我想保留所有功能。那么:出了什么问题?我该如何解决?

1 个答案:

答案 0 :(得分:15)

  

出了什么问题?

Bar A({1,2});

可以解释为:

Bar A(Bar{Foo<std::size_t>(1), (bool)2 /*, true*/ });

Bar A(Foo<std::size_t>{1,2} /*, true, true*/);

如此暧昧的电话。

  

我该如何解决?

这取决于您期望的结果,例如,添加explicit可能有所帮助。

制作explicit Foo(size_t n)只允许:

Bar A(B{Foo<std::size_t>(1), (bool)2 /*, true*/ });