【问题标题】:Member function of class with template arguments and default arguments outside class具有模板参数和类外默认参数的类的成员函数
【发布时间】:2019-12-23 00:49:30
【问题描述】:

我想在模板类之外定义函数,如下所述。

已经为第二个参数尝试了很多组合,它是一个模板并且也采用默认参数。

template <typename T>
class CustomAllocator
{
 //My custom allocator
};

template <typename T, typename Allocator = CustomAllocator<T> >
class CustomContainer
{
 void push_back();
};

/*I want to define push_back outside my class, tried everything.
Almost 4 hours spent through stackoverflow, fluentcpp and all sites*/

// What should be specified for Allocator here ?
template <typename T>
void CustomContainer<T,Allocator>::push_back(T value)
{

}

//OR

template <typename T>
void CustomContainer<T,CustomAllocator<> >::push_back(T value)
{

}

我希望它在类之外定义 实际得到编译器错误,如果是简单类型,我可以在第二个参数中轻松提及 int、float 等。

【问题讨论】:

  • template &lt;typename T, typename Allocator&gt;
  • 在模板定义中,push_back() 没有参数。该函数的两个尝试定义都带有一个参数。在模板类中,将函数声明更改为void push_back(DataType);(假设DataType已在某处定义;它不会出现在示例代码中的任何位置。
  • 对不起,DataType 混淆了,它基本上是 T 类型,我已经编辑了源代码。

标签: c++ function class templates definition


【解决方案1】:

在你的类定义之外,函数不清楚Allocator是什么类型,所以你必须像重新声明T一样重新声明它

template <class T, class Allocator>
void CustomContainer<T,Allocator>::push_back(T value)
{
   // ...
}

(我假设DataType 应该是T

请注意,您在类中的 push_back 声明应与定义匹配:

template <typename T, typename Allocator = CustomAllocator<T> >
class CustomContainer
{
 void push_back(T);
};

【讨论】:

  • 非常感谢!我把它改正给 T。你是怎么得出的?我的意思是为什么不是我尝试的 Allocator ,因为 Allocator 是模板类型,尽管它是默认参数。精彩的答案,至少对我来说!他们说定义中不需要提及默认类型,我尝试过一次,但出现了编译器错误,但可能是指定的参数不是 Allocator 之类的 Allocator.
  • 很难说我是怎么做到的...我猜是多年的经验?至于为什么不Allocator&lt;&gt;。该代码正在尝试使用带有默认模板参数的Allocator 版本,它没有,因此它不会编译(此外,你不会想要它)
  • @Robust Allocator 不是模板。它可能是一个实例化自模板的类型,但它本身不是模板。
  • 嗯...是的,它是从模板启动的类型,既不是完全专业化也不是部分专业化的模板,这种类型必须是模板,因为它的行为和行为非常像模板.它可以作为第二个参数的任何类型的 CustomAllocator,如果我们不提供,它将采用默认值。我从语法的角度理解你的意思,但我不能同意它不是模板本身。
【解决方案2】:

对于在模板定义之外定义的模板的成员函数,您不能使用默认模板参数。

来自 C++ 17 标准(17.1 模板参数)

  1. ...不应在模板中指定默认模板参数- 类成员定义的参数列表 出现在成员班级之外的模板。

那就写吧

template <typename T, typename Allocator>
void CustomContainer<T, Allocator>::push_back( const T &value )
{
    //...
}

注意函数的参数。您对函数的声明与其定义不符。

【讨论】:

  • 但这是模板类的默认模板参数,而不是该模板类的特定成员函数,对吧?如果我们不能在类之外定义它,我们就可以这样做。我的意思是它应该是二进制的,我们可以或我们不能,这可能会令人困惑。
  • @Robust 是的,不能在成员函数定义中使用。即类的所有模板参数都应在模板类之外的成员函数定义中指定。
  • 点了。非常感谢!下面的行很有启发性。 “即类的所有模板参数都应在模板类之外的成员函数定义中指定。”
  • @Robust 更准确的说法应该是定义的成员函数的类的所有模板参数和所有模板参数都应指定
猜你喜欢
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 2011-01-29
相关资源
最近更新 更多