题
您可以在模板类中专门化模板方法而不专门化类模板参数吗?
请注意,该专业是 价值 模板参数的类型,而不是其类型。
这似乎可以在 Visual Studio 2008 SP1 编译器下编译,但不能在 GCC 4.2.4 下编译。
#include <iostream>
using namespace std;
template <typename T>
class A
{
private:
template <bool b>
void testme();
template <>
void testme<true>() { cout << "true" << endl; };
template <>
void testme<false>() { cout << "false" << endl; };
public:
void test();
};
template<typename T> struct select {};
template<> struct select<int> { static const bool value = true; };
template<> struct select<double> { static const bool value = false; };
template <class T>
void A<T>::test() { testme<select<T>::value>(); }
int main(int argc, const char* argv[])
{
A<int> aInt;
A<double> aDouble;
aInt.test();
aDouble.test();
return 0;
}
海湾合作委员会告诉我:“错误:非命名空间范围“A 类”的显式专业化”
如果标准不支持它,谁能告诉我为什么?
解决方案
这是另一种解决方法,当您需要部分专门化函数(这是不允许的)时也很有用。创建一个模板函子类(即类的唯一目的是执行单个成员函数(通常名为 operator() ),对其进行专门化,然后从模板函数中调用。
我想我从赫伯·萨特那里学到了这个技巧,但不记得那是哪本书(或文章)。对于您的需求来说,这可能有点矫枉过正,但尽管如此......
template <typename T>
struct select;
template <bool B>
struct testme_helper
{
void operator()();
};
template <typename T>
class A
{
private:
template <bool B> void testme()
{
testme_helper<B>()();
}
public:
void test()
{
testme<select<T>::value>();
}
};
template<> void testme_helper<true>::operator()()
{
std::cout << "true" << std::endl;
}
template<> void testme_helper<false>::operator()()
{
std::cout << "false" << std::endl;
}
其他提示
标准不支持它(这显然是 Visual Studio 的一个已知错误,您可以 能 做吧)。
标准不允许内部模板(成员函数 或者 class)进行专门化,而外部模板也没有专门化。原因之一是您通常可以重载该函数:
template<typename ty>
class A
{
public:
void foo(bool b);
void foo(int i);
};
相当于:
template<typename ty>
class A
{
public:
template<typename ty2>
void foo(ty2);
template<>
void foo(bool b);
template<>
void foo(int i);
};
操作方法如下:
template<typename A>
struct SomeTempl {
template<bool C> typename enable_if<C>::type
SomeOtherTempl() {
std::cout << "true!";
}
template<bool C> typename enable_if<!C>::type
SomeOtherTempl() {
std::cout << "false!";
}
};
你可以得到 enable_if
从我的另一个答案中,我告诉他们如何使用模板检查类中成员函数是否存在。或者你可以使用boost,但记住要改变 enable_if
到 enable_if_c
然后。
我从来没有听说过这是可能的;如果是的话,这对我来说是有意义的 不是 所有编译器都支持。所以这里有一个解决方法的想法:
在类外部实现一个模板函数,该函数执行与该方法相同的操作。然后你可以专门化这个函数,并从方法中调用它。当然,您还必须传递它需要的任何成员变量(如果您想修改它们的值,还必须传递指向它们的指针)。
您还可以创建另一个模板类作为子类,并专门化该模板类,尽管我自己从未这样做过,并且不能 100% 确定它会起作用。(如果您知道第二种方法是否有效,请发表评论以补充此答案!)