C++ Template:部分模板 模板类中的功能特化

发布于 2024-12-10 17:05:33 字数 505 浏览 5 评论 0原文

我想专门研究模板类中的特定功能。

例如:

template<class T>
class A   
{    
public :  
  void fun1(T val);  
  void fun2(T val1, T val2);
};

template <class T>
void A<T>::fun1(T val)
{
  // some task 1;
}


template <class T>
void A<T>::fun2(T val1, T val2)
{
  // some task 2;
}


template <>
void A<char*>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
}

当我做这样的事情时,我收到错误说 fun2() 的多个定义 请告诉我为什么这是错误的以及实现这一点的正确方法。

I want to specialize specific function in template class.

Eg:

template<class T>
class A   
{    
public :  
  void fun1(T val);  
  void fun2(T val1, T val2);
};

template <class T>
void A<T>::fun1(T val)
{
  // some task 1;
}


template <class T>
void A<T>::fun2(T val1, T val2)
{
  // some task 2;
}


template <>
void A<char*>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
}

when I do something like this, I get error saying multiple definition for fun2()
Please let me why this wrong and also the correct way to implement this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

横笛休吹塞上声 2024-12-17 17:05:33

我建议采用以下方法。定义一个名为implementation私有函数模板来处理一般情况,并重载专门化< /em>) 实现来处理T=char*时的特定情况。然后从 fun2() 调用 implementation 并传递第三个参数,如下所示。将根据模板参数T选择正确的实现

template<class T>
class A   
{    
    template<typename U> struct selector{};

    public :  
        void fun1(T val);  
        void fun2(T val1, T val2)
        {
            //forward the call
            //a correct function will be selected automatically based on T
            implementation(val1, val2, selector<T>());
        }
   private:
        template<typename U>
        void implementation(T & val1, T & val2, const selector<U> &)
        {
           //general case!
        }
        void implementation(T & val1, T & val2, const selector<char*> &)
        {
           //specific case when T = char*
        }
};

类型为selector(或selector<;)的第三个参数。 char*>) 有助于选择正确的实现。

I would suggest the following approach. Define a private function template called implementation to handle the general case, and overload (not specialize) implementation to handle the specific case when T=char*. Then from fun2(), call implementation passing a third argument as shown below. The correct implementation will be selected based on the template argument T:

template<class T>
class A   
{    
    template<typename U> struct selector{};

    public :  
        void fun1(T val);  
        void fun2(T val1, T val2)
        {
            //forward the call
            //a correct function will be selected automatically based on T
            implementation(val1, val2, selector<T>());
        }
   private:
        template<typename U>
        void implementation(T & val1, T & val2, const selector<U> &)
        {
           //general case!
        }
        void implementation(T & val1, T & val2, const selector<char*> &)
        {
           //specific case when T = char*
        }
};

The third argument of type selector<T> (or selector<char*>) helps selecting the correct implementation.

夜清冷一曲。 2024-12-17 17:05:33

您的方法 fun2() 本身不是 template 方法,尽管它是 template 类的成员。我没有找到合适的技术术语,但简单来说,专门化 fun2() 将创建正常函数定义的效果。将定义放在头文件中会出现多个定义错误。

要解决这个问题,只需添加一个内联关键字,链接器错误就会消失!

template <> inline // <----- 'inline' will prompt to generate only 1 copy
void A<char*>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
}

编辑:这可以解决链接器错误。但您仍然无法使用 A::fun2。最终,它归结为这样一个事实:您需要专门化整个类 A重载fun2 A 内的 (char*, char*)

template<class T>
class A
{
  // constructors
public:
  //...
  void fun2(char* val1, char* val2)
  {
    //specific case when T = char*
  }
};

Your method fun2() is not a template method as itself, though it's a member of a template class. I don't find the proper technical term but in simple words, specializing fun2() will create an effect of a normal function definition. Putting the definition in header file will give you multiple definition error.

To solve this problem, just put an inline keyword and the linker error will go away!

template <> inline // <----- 'inline' will prompt to generate only 1 copy
void A<char*>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
}

Edit: This solves the linker error. But still you cannot use the A<char*>::fun2. Ultimately it boils down to the very fact that you need to specialize the whole class A<char*> or overload the fun2(char*, char*) within A<T>

template<class T>
class A
{
  // constructors
public:
  //...
  void fun2(char* val1, char* val2)
  {
    //specific case when T = char*
  }
};
魂归处 2024-12-17 17:05:33

相应地分割你的代码,它应该可以工作,例如:

Ah

template<class T>
class A   
{    
    public :  
        void fun1(T val);  
        void fun2(T val1, T val2);

};

template <class T>
void A<T>::fun1(T val)
{
  // some task 1;
}


template <class T>
void A<T>::fun2(T val1, T val2)
{
  // some task 2;
}

A.cpp

#include <iostream>
#include "A.h"

template <>
void A<char *>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
  std::cout << "char*::fun2" << std::endl;
}

Amain.cpp

#include <iostream>    
#include "A.h"

int main()
{
  A<char*> a;

  char* c= 0;
  char* d= 0;

  a.fun2(c, d);
}

编译和链接,它应该做正确的事情......

Split your code accordingly and it should work, for example:

A.h

template<class T>
class A   
{    
    public :  
        void fun1(T val);  
        void fun2(T val1, T val2);

};

template <class T>
void A<T>::fun1(T val)
{
  // some task 1;
}


template <class T>
void A<T>::fun2(T val1, T val2)
{
  // some task 2;
}

A.cpp

#include <iostream>
#include "A.h"

template <>
void A<char *>::fun2(char* val1, char* val2)
{
  // some task 2 specific to char*;
  std::cout << "char*::fun2" << std::endl;
}

Amain.cpp

#include <iostream>    
#include "A.h"

int main()
{
  A<char*> a;

  char* c= 0;
  char* d= 0;

  a.fun2(c, d);
}

Compile and link, and it should do the right thing...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文