Pimpl idiom and member function templates

Discussion in 'C++' started by Peteris Krumins, Aug 31, 2005.

  1. Hello!

    I was playing around pimpl idiom and discovered that there is a problem
    with it if a class member template function exists which has to access
    private data, since only the forward declaration of pimpl class is
    provided.


    Example:


    class Foo
    {
    private:
    struct foo_impl;
    foo_impl *pimpl;

    public:
    // ...
    //

    template <typename T>
    T bar()
    {
    // bar() has to access private data which is located
    // in pimpl.
    // for example,

    int id = pimpl->baz;

    // ...
    }
    };

    To allow the template be instantiated for any type is has to be
    left in the interface of Foo class. But then it cannot access
    pimpl->baz because pimpl has only been forward declared.

    I have three solutions but I do not like any of them.

    The first solution is to include or write the definition of
    foo_impl class in the same file where Foo's interface is,
    so Foo::foo_impl was defined.

    I don't like because it would not reduce compile times and probably
    will make client code to be recompiled since header file would have
    changed since last compile and most tools for automatic compilation
    look at modification times.

    The second solution is to create a global function which takes
    a reference to Foo and make this function a friend to Foo.

    Example,
    class Foo {
    // ...
    template <typename T>
    friend int bar(Foo &foo);
    // ...
    };

    and somewhere
    template <typename T> int bar(Foo &foo) { return foo->impl->baz; }

    As bar() is friend to Foo, it can access private pimpl.

    I don't like this solution because i break interface of Foo, instead
    of a convenient member function a global has to be added and an object
    has to be passed to this function.

    The third solution is the simplest, bring the particular private member
    which has to be accessed in template function back to private section
    of Foo.
    I don't like it cause I have to expose implementation details which is
    what pimpl helps me not to do.


    Can anyone think of more solutions to this problem? Maybe there is
    a direct solution which allows somehow to keep the original
    design and access pimpl members?


    Thanks!


    P.Krumins
     
    Peteris Krumins, Aug 31, 2005
    #1
    1. Advertising

  2. Peteris Krumins

    Alipha Guest

    Peteris Krumins wrote:
    > Hello!
    >
    > I was playing around pimpl idiom and discovered that there is a problem
    > with it if a class member template function exists which has to access
    > private data, since only the forward declaration of pimpl class is
    > provided.
    >
    > [snip]


    if the number of possible template arguments is small, you can do
    explicit template instantiation:

    // .h file:

    class Foo {
    public:
    template<class T>
    void bar(T x);
    };

    // .cpp file:
    template void Foo::bar(int);
    template void Foo::bar(long);
    template void Foo::bar(float);

    Otherwise, you're trying to mix two things that are incompatiable:
    separate compilation and templating. You COULD also get one of those
    rare compilers which support the export keyword... (comeau is the only
    one I know of) Of course, so much for portability in that case.
     
    Alipha, Aug 31, 2005
    #2
    1. Advertising

  3. >
    > if the number of possible template arguments is small, you can do
    > explicit template instantiation:
    >
    > [snip]
    >
    > Otherwise, you're trying to mix two things that are incompatiable:
    > separate compilation and templating. You COULD also get one of those
    > rare compilers which support the export keyword... (comeau is the only
    > one I know of) Of course, so much for portability in that case.


    Thanks!

    Unfortunately that member template function works like a factory and
    I can't explicitly instantiate because I don't know all types which
    will
    be constructed with it.

    I chose to bring one of the pimpl members back to the class to solve
    the problem till more compilers start supporting export keyword!


    P.Krumins
     
    Peteris Krumins, Aug 31, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Icosahedron

    Pimpl Idiom

    Icosahedron, Nov 20, 2003, in forum: C++
    Replies:
    7
    Views:
    706
    Icosahedron
    Nov 22, 2003
  2. Debajit  Adhikary
    Replies:
    2
    Views:
    2,039
    Christopher Benson-Manica
    Jul 15, 2004
  3. jimmy

    friendship and pImpl idiom

    jimmy, Feb 8, 2006, in forum: C++
    Replies:
    3
    Views:
    445
    Alf P. Steinbach
    Feb 9, 2006
  4. Noah Roberts

    pimpl idiom and singletons

    Noah Roberts, May 24, 2007, in forum: C++
    Replies:
    4
    Views:
    437
    Noah Roberts
    May 25, 2007
  5. Daniel Lidström
    Replies:
    15
    Views:
    639
    Brendon Costa
    Oct 31, 2007
Loading...

Share This Page