我有一个模板类,它具有需要专门化的模板成员函数,如:
template <typename T>
class X
{
public:
template <typename U>
void Y() {}
template <>
void Y<int>() {}
};
Altough VC正确处理此问题,显然这不是标准问题,GCC抱怨:explicit specialization in non-namespace scope 'class X<T>'
我试过了:
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抱怨。
这样做的正确方法是什么?
答案 0 :(得分:8)
很常见的问题。解决问题的一种方法是通过重载
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>) { }
};
答案 1 :(得分:0)
使用Helper类删除类专门化
示例1
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
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;
}