Specializing a template member function of a template class?
我有一个模板类,它具有需要专门化的模板成员函数,如下所示:
1 2 3 4 5 6 7 8 9 10 | template <typename T> class X { public: template <typename U> void Y() {} template <> void Y<int>() {} }; |
完全VC可以正确处理此问题,显然这不是标准的,GCC抱怨:
我试过了:
1 2 3 4 5 6 7 8 9 10 11 | template <typename T> class X { public: template <typename U> void Y() {} }; template <typename T> // Also tried `template<>` here void X< T >::Y<int>() {} |
但这会使VC和GCC都抱怨。
什么是正确的方法?
非常普遍的问题。 解决它的一种方法是通过重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | template <typename T> struct type2type { typedef T type; }; template <typename T> class X { public: template <typename U> void Y() { Y(type2type<U>()); } private: template<typename U> void Y(type2type<U>) { } void Y(type2type<int>) { } }; |
Use a Helper class to remove the class specialization
例子1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | namespace { /* Make this work template <typename T> class X { public: template <typename U> void Y() {} template <> void Y<int>() {} }; */ template <typename K> struct IntegerHelper { static bool isInteger() { return false; } }; template <> inline bool IntegerHelper<int>::isInteger() { return true; } template <typename T> class TestX { public: template <typename K> static bool isInteger() { return IntegerHelper<K>::isInteger(); } }; } TEST(TestTemplateMethodSpecialization, Basic) { EXPECT_TRUE(TestX<double>::isInteger<int>()); EXPECT_FALSE(TestX<double>::isInteger<double>()); } |
例子2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | enum class Side { BUY = 0, SELL }; using PriceType = int64_t; class BookHelper { public: BookHelper( PriceType insideBuyPrice, PriceType insideSellPrice) : insideBuyPrice_{insideBuyPrice}, insideSellPrice_{insideSellPrice} { } template <Side SideV> PriceType insidePrice() const; template <Side SideV> void insidePrice(PriceType price); private: PriceType insideBuyPrice_; PriceType insideSellPrice_; }; template <> inline void BookHelper::insidePrice<Side::BUY>(PriceType price) { insideBuyPrice_ = price; } template <> inline void BookHelper::insidePrice<Side::SELL>(PriceType price) { insideSellPrice_ = price; } template <> inline PriceType BookHelper::insidePrice<Side::BUY>() const { return insideBuyPrice_; } template <> inline PriceType BookHelper::insidePrice<Side::SELL>() const { return insideSellPrice_; } template <typename BookT> class Book { public: Book(); template <Side SideV> PriceType insidePrice() const; template <Side SideV> void insidePrice(PriceType price); private: std::unique_ptr<BookHelper> helper_; }; template<typename BookT> Book<BookT>::Book() : helper_{new BookHelper{std::numeric_limits<PriceType>::min(), std::numeric_limits<PriceType>::max()}} {} template <typename BookT> template <Side SideV> PriceType Book<BookT>::insidePrice() const { return helper_->insidePrice<SideV>(); } template <typename BookT> template <Side SideV> void Book<BookT>::insidePrice(PriceType price) { helper_->insidePrice<SideV>(price); } class TestBook { }; int main() { Book<TestBook> test; test.insidePrice<Side::SELL>(1230046); test.insidePrice<Side::BUY>(1230045); std::cout <<" inside SELL price :" << test.insidePrice<Side::SELL>() << std::endl; std::cout <<" inside BUY price :" << test.insidePrice<Side::BUY>() << std::endl; } |