2
votes

I'm trying to implement bind function from boost library. Below you can see the main struct bind_t with defined operator().

My question is as follows: Why should we specify in decltype in returning type of operator() returning type of call() explicitly as member function (if I remove this-> before call, the template argument deduction fails in g++.)

Also interesting, that using clang++ there's no such problem.

I have no idea, why this happens.

template <typename F, typename  ... P>
struct bind_t {
private:
    std::tuple<typename holder<P>::type...> p;
    F func;
    template <size_t ... N, typename ... Args>
    auto call(index_list<N ...>, Args const& ... args) const -> decltype(func(std::get<N>(p)(args...)...)) {
        return func(std::get<N>(p)(args...)...);
    }
public:
    bind_t(F f, P ... p):
        p(std::move(p)...),
        func(std::move(f))
    {}
    template <typename ... Args>
    auto operator()(Args const& ... args) const -> decltype(this->call(typename indices_by_num<sizeof...(P)>::type(), args...)) {
        typename indices_by_num<sizeof...(P)>::type indices;
        return call(indices, args...);
    }
};

full source of implementation
simple usecase

1
Looks like it is fixed in gcc 5.1 - Shafik Yaghmour

1 Answers

2
votes

This is a gcc bug and is documented in the bug report decltype needs explicit 'this' pointer in member function declaration of template class with trailing return type which says:

When using trailing return-type for member functions of a template class, the 'this' pointer must be explicitly mentioned. This should not be necessary (The implicit 'this' works with a non-template class).

Example:

template <typename T>
struct DecltypeConstThis {

    T f() const { return T{}; }

    auto g() -> decltype(this->f()) { return this->f(); }
    auto h() const  ->  decltype(f()) { return f(); } // this should work the same as g() above (with implicit 'this')

};

struct Working {
    int f() const { return 0; }
    auto h() const -> decltype(f()) { return 0; }
};


int main() {

    Working w;
    w.h();

    DecltypeConstThis<int> d;
    d.g();
    d.h();

    return 0;
}

The report was marked as fixed and it looks like this works starts working in gcc 5.1 (see it live).