template<typename T>
struct foo
{
T* p;
foo(T* x) : p(x) {}
~foo() { if(p) delete p; }
T& operator*() const { return *p; }
};
int main()
{
foo<int> i(new int);
foo<void> v(new int); // <= illegal use of type 'void'
}
如果T = void,那么我不想实现运算符*()。我怎样才能做到这一点?我不想专门化这个课,因为我班上还有很多其他的方法。
PS:请注意,这只是解释我的问题的一个例子。
答案 0 :(得分:6)
您可以将所有其他方法(与T==void
配合使用)移动到基类中,并使foo
从中派生出来。然后,foo
可以专门用于不为operator*
T==void
template <typename T>
struct foobase {
T* p;
foobase(T* x) : p(x) {}
~foobase() { if(p) delete p; }
};
template <typename T>
struct foo : foobase<T> {
T& operator*() const { return *p; }
};
template<>
struct foo<void> : foobase<void> {
};
答案 1 :(得分:5)
C ++ 11标准为std::unique_ptr
解决了这个问题:
typename std::add_lvalue_reference<T>::type
operator*() const { return *p; }
答案 2 :(得分:3)
就像那样:
template<typename T>
struct foo_base
{
T* p;
foo(T* x) : p(x) {}
~foo() { if(p) delete p; }
// other methods …
};
template<typename T>
struct foo : foo_base<T>
{
T& operator*() const { return *p; }
};
template<>
struct foo<void> : foo_base<void>
{
};
答案 3 :(得分:1)
怎么样
typename disable_if<is_void<T>, T>::type& operator* () const { return *p;}
还是我错过了一些明显的东西?
答案 4 :(得分:0)
这个解决方案是什么:
template<typename T>
struct foo
{
T* p;
foo(T* x) : p(x) {}
~foo() { if(p) delete p; }
template<typename U> struct impl { U& deref(U* p) { return *p; } };
template<> struct impl<void> { void deref(void* p) { } };
typename boost::conditional<std::is_void<T>::value, T, typename std::add_reference<T>::type>::type operator*() const
{
static_assert(!std::is_void<T>::value, "illegal use of type 'void'");
return impl<T>().deref(p);
}
};