4

您可以在不专门化类模板参数的情况下专门化模板类中的模板方法吗?

请注意,特化是模板参数的,而不是它的类型。

这似乎在 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;
}

GCC 告诉我:“错误:非命名空间范围 'class A' 中的显式特化”

如果标准不支持,谁能告诉我为什么?

4

4 回答 4

4

标准不支持它(显然这是 Visual Studio 的一个已知错误,您可以这样做)。

该标准不允许在没有专门化外部模板的情况下专门化内部模板(成员函数或类)。原因之一是您通常可以重载函数:

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);
};
于 2008-09-15T17:14:22.943 回答
2

这是你的做法:

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从我告诉他们如何使用模板检查类中成员函数的存在的其他答案中获得。enable_if或者你可以使用boost ,但记得改成enable_if_cthen。

于 2008-11-08T21:15:35.577 回答
1

这是另一种解决方法,当您需要对函数进行部分特化(这是不允许的)时也很有用。创建一个模板仿函数类(即,其唯一目的是执行单个成员函数的类,通常命名为 operator() ),对其进行专门化,然后从模板函数中调用。

我想我从 Herb Sutter 那里学到了这个技巧,但不记得那是哪本书(或文章)。对于您的需要,这可能是矫枉过正,但尽管如此......

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;
}
于 2008-09-15T22:03:09.117 回答
0

我从来没有听说过这是可能的。如果不是所有编译器都支持它,那对我来说是有意义的。所以这里有一个解决方法的想法:

在你的类之外实现一个模板函数,它采取与方法相同的动作。然后你可以专门化这个函数,并从方法中调用它。当然,你还必须传入它需要的任何成员变量(如果你想修改它们的值,还需要指向它的指针)。

您还可以创建另一个模板类作为子类,并专门化那个模板类,尽管我自己从未这样做过,也不能 100% 确定它会起作用。(如果您知道第二种方法是否可行,请发表评论以补充此答案!)

于 2008-09-15T17:24:09.100 回答