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