错误:类型为"bar&"的参数的默认参数<int>具有类型"bar<int>"



我在编译时遇到上述错误,如何纠正它。请帮我解决这个问题

#include <iostream>
using namespace std;
template <typename T>
class bar
{
 public:
 bar(){cout << "bar" <<"n";}
};
template <typename T, typename ctor = bar<T>>
class foo
{
 T i;
public:
 explicit foo(ctor& c = ctor());
private:
 ctor mctor;

};
template <typename T, typename ctor>
foo<T,ctor>::foo(ctor& c):mctor(c)
{
 cout << "foo" <<"n";
}
int main()
{
 foo<int> f;
 return 0;
}

编译:g++ -std=c++11 ctor_call.cpp

您正在为应该通过此行中的引用传递的参数提供默认参数:

explicit foo(ctor& c = ctor());

此处,ctor&是对类型 ctor 的对象的引用。 因此,只要您有对它的引用,该对象就需要存在。 但是默认参数将其设置为即将销毁的临时对象。 由于临时对象不是标准化的,因此可以在构造函数开始之前销毁它,因此您将不保留对任何内容的引用。 在这个答案中,对这一切有一个很好的解释。

模板使您的情况稍微复杂一些,因此让我们更具体一点。 默认ctor()是对要引用的对象的构造函数的调用。 在您的情况下,类是foo<int> ,因此模板看起来像

template <int, typename ctor = bar<int>>
class foo

在这里,模板正在获取第二个参数,但它是默认参数,因此您可以获得ctor = bar<int> . 这相当于使用 foo<int, bar<int>> 。 现在,在你的函数语句中,ctor()实际上与bar<int>()相同 - 它是对构造函数的调用。

一些可能的解决方案

1) 不要传递默认值:

explicit foo(ctor& c);

2)不要通过引用:

explicit foo(ctor c = ctor());

3) 通过常量引用传递:

explicit foo(const ctor& c = ctor());

这有点神奇,因为const使编译器保留临时对象,直到 const 引用被销毁,这出现在 foo 构造函数调用的末尾。

4) 使用存在于foo对象之外的东西,例如静态或全局对象。 (虽然你应该警惕静态,我们基本上都讨厌全局变量......

explicit foo(ctor& c = some_ctor_object_that_exists_already);