我正在尝试将pImpl惯用法与类模板一起使用,并且在模板参数为void
时遇到问题。这是我最新的人为例子:
#include <memory>
template<typename T> class Foo {
class Impl;
std::shared_ptr<Impl> pImpl;
public:
Foo()
: pImpl{new Impl()} {
}
void set(T value) {
pImpl->set(value);
}
T get() {
return pImpl->get();
}
};
template<typename T> class Foo<T>::Impl {
T value;
public:
void set(T value) {
this->value = value; // among other things
}
T get() {
return value; // among other things
}
};
template<> class Foo<void> {
class Impl;
std::shared_ptr<Impl> pImpl;
public:
void set() {
pImpl->set();
}
void get() {
pImpl->get();
}
};
class Foo<void>::Impl {
public:
void set() {
// do useful stuff
}
void get() {
// do useful stuff
}
};
在以下内容中编译以上结果:
$ g++ -dumpversion
4.8.5
void_int_template.cpp: In member function ‘void Foo<void>::set()’:
void_int_template.cpp:34:14: error: invalid use of incomplete type ‘class Foo<void>::Impl’
pImpl->set();
^
void_int_template.cpp:30:27: error: forward declaration of ‘class Foo<void>::Impl’
class Impl;
^
void_int_template.cpp: In member function ‘void Foo<void>::get()’:
void_int_template.cpp:37:14: error: invalid use of incomplete type ‘class Foo<void>::Impl’
pImpl->get();
^
void_int_template.cpp:30:27: error: forward declaration of ‘class Foo<void>::Impl’
class Impl;
^
如何专门化类模板以容纳void
模板参数?
答案 0 :(得分:1)
完全专业化提供了另一种定义,这意味着您必须重新定义所有内容。
template<> class Foo<void> {
class Impl;
std::shared_ptr<Impl> pImpl;
public:
Foo();
void set();
void get();
};
class Foo<void>::Impl {
public:
void set() {
}
void get() {
}
};
// these need to be inline iff it's in your header file
/* inline */ Foo<void>::Foo() : pImpl(new Impl) {}
/* inline */ void Foo<void>::set() { pImpl->set(); }
/* inline */ void Foo<void>::get() { pImpl->get(); }