我试图使用类模板的pImpl成语,并且当模板参数为void
时遇到问题。这里是我的最新的人为的例子:C++ 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
模板参数?
类模板专业化不是对原始模板的“调整” - 它本身就是一个单独的类,除了与原始模板相同的名称外没有其他任何东西。正如你所假设的那样,它不会以某种方式继承其成员。您观察到的直接问题是'template <> class Foo :: Impl {...}'会导致'Foo '的隐式实例化,然后您为此提供明确的专门化。这使程序不合格(通过违反ODR的方式,我认为但不确定)。 –