C++ 为类模板的单个成员定义专门化

C++ 为类模板的单个成员定义专门化,c++,templates,syntax,C++,Templates,Syntax,我有一个模板类(或者它是一个类模板?),包含许多成员函数。我对它们都有定义。我想覆盖其中一个定义,对于一个特定的T值。我希望我不必为这个特定的T值提供所有成员函数的定义,因为它们都与泛型T的定义相同 我尝试了下面的方法,但我得到一个链接器错误“…找到一个或多个多重定义符号” 我是用错语法还是我在C++中做了一些不允许的事情? template <typename T> struct A { void a(T); void b(T); ... void

我有一个模板类(或者它是一个类模板?),包含许多成员函数。我对它们都有定义。我想覆盖其中一个定义,对于一个特定的T值。我希望我不必为这个特定的T值提供所有成员函数的定义,因为它们都与泛型T的定义相同

我尝试了下面的方法,但我得到一个链接器错误“…找到一个或多个多重定义符号”

<>我是用错语法还是我在C++中做了一些不允许的事情?
template <typename T>
struct A
{
    void a(T);
    void b(T);
    ...
    void z(T);
};

void A<int>::a(int)
{
    // do something special for this particular template parameter
}

template <typename T>
void A<T>::a(T){}

template <typename T>
void A<T>::b(T){}

...

template <typename T>
void A<T>::z(T){}
模板
结构A
{
无效a(T);
无效b(T);
...
空位z(T);
};
void A::A(int)
{
//为此特定模板参数执行一些特殊操作
}
样板
void A::A(T){}
样板
void A::b(T){}
...
样板
void A::z(T){}
具体来说,下面是一些真正的代码,它们会导致相同的问题:

template<typename T>
struct A
{ 
    void f(T);
};

template<> // same linker error with or without this line
void A<int>::f(int)
{
    // something special
}

template<typename T>
void A<T>::f(T)
{
}
模板
结构A
{ 
空隙f(T);
};
模板//有或没有此行时出现相同的链接器错误
空A::f(int)
{
//特别的东西
}
样板
空A::f(T)
{
}

您几乎是对的,只是缺少了表示明确专业化的
模板:

template<>
void A<int>::a(int)
{
}
模板
void A::A(int)
{
}
编辑:下面的答案正确地指出,如果希望在标题中包含此实现,则应使用
内联
说明符。或者,您可以选择将实现移动到源文件,
在这种情况下,您仍然应该在头文件中声明显式专门化。换句话说,它遵循常规的函数定义规则。

您几乎是正确的,只是缺少了表示显式专门化的
模板:

template<>
void A<int>::a(int)
{
}
模板
void A::A(int)
{
}
编辑:下面的答案正确地指出,如果希望在标题中包含此实现,则应使用
内联
说明符。或者,您可以选择将实现移动到源文件, 在这种情况下,您仍然应该在头文件中声明显式专门化。换句话说,它遵循常规的函数定义规则

我希望我不必为t的这个特定值提供所有成员函数的定义,因为它们都与泛型t的定义相同

如果您可以使用C++11,一个可能的解决方案是SFINAE启用/禁用通用或
int
specific
a()
version

差不多

template <typename T>
struct A
 {
   template <typename U = T>
   typename std::enable_if<false == std::is_same<int, U>{}>::type a(T)
    { std::cout << "generic version" << std::endl; }

   template <typename U = T>
   typename std::enable_if<true == std::is_same<int, U>{}>::type a(T)
    { std::cout << "integer version" << std::endl; }

   void b(T) {}
   void z(T) {}
 };
std::enable_if
的测试可以修改为检查
T
U
是否为同一类型

   template <typename U = T>
   typename std::enable_if<(false == std::is_same<int, U>{})
                        && (true == std::is_same<T, U>{})>::type a(T)
    { std::cout << "generic version" << std::endl; }

   template <typename U = T>
   typename std::enable_if<(true == std::is_same<int, U>{})
                        && (true == std::is_same<T, U>{})>::type a(T)
    { std::cout << "integer version" << std::endl; }
您的
A
struct
可以编写

template <typename T>
struct A
 {
   template <typename U>
   typename enableIf<(false == isSame<int, U>::value)
                  && (true == isSame<T, U>::value), void>::type a(U)
    { std::cout << "generic version" << std::endl; }

   template <typename U>
   typename enableIf<(true == isSame<int, U>::value)
                  && (true == isSame<T, U>::value), void>::type a(U)
    { std::cout << "integer version" << std::endl; }

   void b(T) {}
   void z(T) {}
 };
模板
结构A
{
样板
typename enableIf::类型a(U)
{std::cout
我希望我不必为t的这个特定值提供所有成员函数的定义,因为它们都与泛型t的定义相同

如果您可以使用C++11,一个可能的解决方案是SFINAE启用/禁用通用或
int
specific
a()
version

差不多

template <typename T>
struct A
 {
   template <typename U = T>
   typename std::enable_if<false == std::is_same<int, U>{}>::type a(T)
    { std::cout << "generic version" << std::endl; }

   template <typename U = T>
   typename std::enable_if<true == std::is_same<int, U>{}>::type a(T)
    { std::cout << "integer version" << std::endl; }

   void b(T) {}
   void z(T) {}
 };
std::enable_if
的测试可以修改为检查
T
U
是否为同一类型

   template <typename U = T>
   typename std::enable_if<(false == std::is_same<int, U>{})
                        && (true == std::is_same<T, U>{})>::type a(T)
    { std::cout << "generic version" << std::endl; }

   template <typename U = T>
   typename std::enable_if<(true == std::is_same<int, U>{})
                        && (true == std::is_same<T, U>{})>::type a(T)
    { std::cout << "integer version" << std::endl; }
您的
A
struct
可以编写

template <typename T>
struct A
 {
   template <typename U>
   typename enableIf<(false == isSame<int, U>::value)
                  && (true == isSame<T, U>::value), void>::type a(U)
    { std::cout << "generic version" << std::endl; }

   template <typename U>
   typename enableIf<(true == isSame<int, U>::value)
                  && (true == isSame<T, U>::value), void>::type a(U)
    { std::cout << "integer version" << std::endl; }

   void b(T) {}
   void z(T) {}
 };
模板
结构A
{
样板
typename enableIf::类型a(U)
{std::cout
模板void A::f(int)
不再是模板。因此不再是
内联的

您必须在cpp中实现它(并在标题中声明)

或者添加
inline
以避免有多个定义(因此定义在标题中)

模板内联void A::f(int)
{
//特别的东西
}
模板void A::f(int)
不再是模板。因此不再是
内联的

您必须在cpp中实现它(并在标题中声明)

或者添加
inline
以避免有多个定义(因此定义在标题中)

模板内联void A::f(int)
{
//特别的东西
}

多亏了上面的回复者。我的问题主要是缺少了内联关键字。以下是有效的方法(意译)

//在头文件中:
样板
结构A
{
无效a(T);
无效b(T);
...
空位z(T);
};
样板
void A::A(T){}
样板
void A::b(T){}
...
样板
void A::z(T){}
//在.cpp文件中:
样板
内联void A::A(int)
{
//为此特定模板参数执行一些特殊操作
}

多亏了上面的回复者。我的问题主要是缺少了内联关键字。以下是有效的方法(意译)

//在头文件中:
样板
结构A
{
无效a(T);
无效b(T);
...
空位z(T);
};
样板
void A::A(T){}
样板
void A::b(T){}
...
样板
void A::z(T){}
//在.cpp文件中:
样板
内联void A::A(int)
{
//为此特定模板参数执行一些特殊操作
}

“类模板”是一个合适的术语:)@Someprogrammerdude这个问题涉及显式实例化,而不是显式专门化。我真的不理解这两个术语之间的区别。我怀疑这是我无法实现此功能的部分原因。有简单的解决方法吗?(我最近对原始帖子的编辑表明,简单地添加行模板没有任何效果)。我发布了一个答案,展示了一种解决方法,但从技术上讲,你不能只专门化单个类方法。(你必须专门化类,因此你要重新实现它的所有方法)@JosephFranciscus“但从技术上讲,你不能只专门化单个类方法。”“类模板”是合适的术语:)@Someprogrammerdude这个问题涉及显式实例化,而不是显式专门化
 // in header file:

template <typename T>
struct A
{
    void a(T);
    void b(T);
    ...
    void z(T);
};

template <typename T>
void A<T>::a(T){}

template <typename T>
void A<T>::b(T){}

...

template <typename T>
void A<T>::z(T){}

// in .cpp file:
template <typename T>
inline void A<int>::a(int)
{
    // do something special for this particular template parameter
}