【问题标题】:c++ template partial specializationc++模板偏特化
【发布时间】:2013-07-09 11:36:24
【问题描述】:

这可能是以前有人问过的问题,但我找不到...

我在.hpp 文件中有一个类:

class A{
    public:
        A(){//constructor}
        ~A(){//destructor}
        //some public methods and arguments

        template<typename Type>
            void func(Type t){//do something for numbers}

    private:
        //some private methods and arguments
}

模板方法应该适用于 int、double... 但不适用于字符串。因此,在我的.hpp 文件中,我定义了func 对数字的作用,并在我的.cpp 文件中写道:

template<>
void A::func(std::string t){ // do something in that case}

但是当我将函数funcstd::string 一起使用时,程序会调用数字的方法...所以我将.hpp 文件替换为:

class A{
    public:
        A(){//constructor}
        ~A(){//destructor}
        //some public methods and arguments

        template<typename Type>
            void func(Type t){//do something for numbers}
        void func(std::string s);

    private:
        //some private methods and arguments
}

我的.cpp 文件变成了:

void A::func(std::string t){ // do something in that case}

然后一切正常!

我的问题是,这是正确的做法吗?

【问题讨论】:

  • 我想第二个大块是 hpp,而不是 cpp?真的吗?
  • 是的,我编辑了那个错误......对不起
  • 没有 pb,我只是不确定,所以我没有自己编辑。

标签: c++ templates specialization


【解决方案1】:

这不是部分特化(没有模板参数未特化),而是显式特化。

模板必须对使用它们的代码可见,如果您没有在头文件中声明特化,那么尝试使用 string 调用 A::func 的代码将实例化主模板(用于数字的模板) ) 并使用它,因为他们甚至不知道 `string specialization 存在。

因此,您必须(至少)在标头中声明特化,以便它可以在 .cpp 文件之外使用:

template<>
void A::func(std::string t);

但是,您使用重载的替代方案更简单并且完全可以接受。它之所以有效,是因为 string 的重载在标头中声明,因此调用它的代码知道要调用哪个函数。

【讨论】:

  • 如果我理解正确,标题必须包含template&lt;&gt; void func(std::string s){//to something}void func(std::string s){//do something}
  • 不,您没有正确理解。这些是定义。标头只需要包含声明,而不是定义(如果标记为inline,它也可以包含定义)
  • 但是对于模板,定义在头文件中......对吧?!
  • 如果头文件直接给出定义,则可以包含定义,我的意思是在类定义中......对吗?!
  • 对于类模板和非专用函数模板和内联函数,定义必须在头文件中。类定义中的成员函数定义是隐式内联的。
【解决方案2】:

重载是一种适用于多种用途的好方法。但是,我怀疑如果您也为 const char * 添加专业化,您的原始模板方法也可以工作。这样,您可以传入字符串文字而不解析为数字版本。

【讨论】:

  • 不知道我理解你的意思......什么是“解决数字版本”?
  • 在最初的问题中,您指出正在调用数字方法而不是专门用于字符串的方法。我可能是错的,但我猜你是在传递一个字符串文字?字符串文字解析为const char *,这是一种数字类型,这就是它调用 numbers 方法而不是字符串方法的原因。
  • 像这样:func("blalba")?不,我传递了这样的字符串std::string s("blabla"); func(s)
  • 哦,我明白了。我的错。无论如何,我看到问题在另一个答案中得到了解决。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-05
  • 1970-01-01
相关资源
最近更新 更多