vendredi 2 juin 2017

C++ Pimpl idiom, class templates, and void template parameter

I'm trying to use the pImpl idiom with class templates and am encountering a problem when the template parameter is void. Here's my contrived example with the fewest errors:

#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;
    }
    T get() {
        return value;
    }
};

template<> class Foo<void>::Impl {
public:
    void set() {
    }
    void get() {
    }
};

template<> class Foo<void> {
public:
    void set() {
        pImpl->set();
    }
    void get() {
        pImpl->get();
    }
};

Compiling the above results in the following:

$ g++ -dumpversion
4.8.5
$ g++ -c -std=c++11 void_int_template.cpp
void_int_template.cpp: In instantiation of ‘class Foo<void>’:
void_int_template.cpp:29:31:   required from here
void_int_template.cpp:10:14: error: invalid parameter type ‘void’
         void set(T value) {
              ^
void_int_template.cpp:10:14: error: in declaration ‘void Foo<T>::set(T)’
void_int_template.cpp:37:22: error: specialization of ‘Foo<void>’ after instantiation
     template<> class Foo<void> {
                      ^
void_int_template.cpp:37:22: error: redefinition of ‘class Foo<void>’
void_int_template.cpp:3:32: error: previous definition of ‘class Foo<void>’
     template<typename T> class Foo {
                                ^

How can I specialize the class templates to accommodate a void template parameter?

Aucun commentaire:

Enregistrer un commentaire