lundi 4 juin 2018

Unexpected nullptr in expansion of variadic template constructor

Difficult to explain, here a short stand-alone example of what I mean:

#include <functional>
#include <iostream>

typedef std::function<void(void)> f_t;

struct A { A(f_t f) { f(); } };
struct B { B(f_t f) { f(); } };
struct C { C(f_t f) { f(); } };

template<typename ... TT>
struct T : TT...
{
    T( ) : TT([this](void) { std::cout << this << std::endl; })...
    {
    }
};

int main(void)
{
    T<A, B, C> t;

    return 0;
}

Output:

0x7ffe84574e6f
0
0

My class template T inherits from its template parameter pack TT. Each type of TT expects a functor as constructor argument. When I try to pass a functor that captures this during the constructor calls, all but the first constructor call of the expansion actually receive a functor that captured nullptr as this. If I delegate the functor creation to a member function, it works as intended:

template<typename ... TT>
struct T : TT...
{
    T( ) : TT(genF())...
    {
    }

    f_t genF( ) { return [this](void) { std::cout << this << std::endl; }; }
};

Output:

0x7ffefca4e61f
0x7ffefca4e61f
0x7ffefca4e61f

(Compiler used is GCC 4.6.3)

What causes this behavior? Is it a compiler bug? Or am I missing something?

Aucun commentaire:

Enregistrer un commentaire