[英]Call to template base constructor is ambiguous
The following code 以下代码
template<class T>
struct Bar
{
Bar(T& myT){}
Bar(const Bar&) = delete;
};
template<class T>
struct Foo: public T,
public Bar<T>
{
Foo(): Bar<T>(*this){}
};
class Baz{};
int main()
{
Foo<Baz> myFoo;
return 0;
}
Gives me this error: 给我这个错误:
error: call to constructor of 'Bar<Baz>' is ambiguous
How can I fix this? 我怎样才能解决这个问题?
(Seems simple, I'm sure there's a duplicate somewhere, but I couldn't find it... all questions I found with "ambiguous constructor" stuff had to do with overloaded constructors, and this seems different to me.) (看似简单,我确定某个地方有重复项,但我找不到它……我发现的关于“模糊构造函数”的所有问题都与重载构造函数有关,这对我来说似乎是不同的。)
You have two constructors in Bar<Baz>
: Bar<Baz>
有两个构造函数:
Bar(Baz& );
Bar(const Bar& );
The fact that the second is deleted doesn't matter for the purposes of overload resolution. 为了重载解决方案,第二个被删除的事实并不重要。 You are trying to construct it from a
Foo<Baz>&
... which is both a Baz
and a Bar<Baz>
, so both overloads apply - and the compiler can't prefer one over the other, so gives you the ambiguous error. 您正在尝试从
Foo<Baz>&
...构造它,它既是Baz
又是Bar<Baz>
,所以这两种重载都适用-编译器不能偏重于另一种,因此给您带来歧义错误。 Here's a simpler example with no templates that demonstrates the same issue: 这是一个没有模板的简单示例,它演示了相同的问题:
struct A { };
struct B { };
struct C : A, B { };
void foo(A& ) { }
void foo(B& ) { }
int main() {
C c;
foo(c); // error: call of overloaded ‘foo(C&)’ is ambiguous
}
To break the ambiguity, could just explicitly tell the compiler which overload to use with casting: 为了消除歧义,可以明确地告诉编译器在强制转换中使用哪个重载:
Foo(): Bar<T>(static_cast<T&>(*this)) {} // will call Bar(Baz&)
Deleted constructors participate in overload resolution. 删除的构造函数将参与重载解析。 This is in order to ensure that the compilation really fails if a program attempts to use a deleted constructor.
这是为了确保如果程序尝试使用已删除的构造函数,则编译实际上会失败。 See this answer for more details.
有关更多详细信息,请参见此答案 。
The relevant section in the C++11 standard is 8.4.3/2: C ++ 11标准的相关部分是8.4.3 / 2:
A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.
隐式或显式引用已删除函数(而不是对其进行声明)的程序格式错误。
[ Note: This includes calling the function implicitly or explicitly and forming a pointer or pointer-to-member to the function.
[注意:这包括隐式或显式调用该函数,并形成该函数的指针或成员指针。 It applies even for references in expressions that are not potentially-evaluated.
它甚至适用于未经过评估的表达式中的引用。 If a function is overloaded, it is referenced only if the function is selected by overload resolution.
如果某个函数被重载,则仅当通过重载分辨率选择该函数时才引用该函数。 —end note ]
—尾注]
You can solve your problem by making the constructor call unambiguous: 您可以通过使构造函数明确调用来解决您的问题:
template<class T>
struct Foo: public T,
public Bar<T>
{
Foo(): Bar<T>(static_cast<T &>(*this)){}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.