Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Access this in New Function Declarator Syntax

Tags:

c++

c++11

When using the new function declarator syntax and decltype, how does one access members? It appears that this is not accessible:

template <typename Func>
struct context_binder
{
public:
    context_binder(const Func& func) :
            func(func)
    { }

    template <typename... TArgs>
    auto operator ()(TArgs&&... args) const
            -> decltype(this->func(std::forward<TArgs>(args)...))
    {
        return func(std::forward<TArgs>(args)...);
    }
private:
    Func func;
};

This yields the compiler error:

scratch.cpp:34:25: error: invalid use of ‘this’ at top level

My compiler is g++ 4.6.2.


My workaround is to declare a static member called self with the same type as the class, which has two problems:

  1. It will not pick up the CV-qualifiers automatically, like this would.
  2. I have to move the member declarations above the decltype usage or it can't see the member (although that seems more like a compiler bug).
like image 500
Travis Gockel Avatar asked Feb 21 '12 21:02

Travis Gockel


2 Answers

Upgrade to GCC 4.7. Version 4.6 doesn't support this where you're trying to use it.

Another question covers some workarounds you might be able to use.

like image 153
Rob Kennedy Avatar answered Sep 29 '22 23:09

Rob Kennedy


You have two errors. The one error is what you spotted yourself. The other error is that you try to access the member before it is declared. Declare it before you use it (notice that the return type, even if it is specified in a trailing manner, cannot access members you declare later, unlike the function body).

template <typename Func>
struct context_binder
{
private:
    Func func;

public:
    context_binder(const Func& func) :
            func(func)
    { }

    template <typename... TArgs>
    auto operator ()(TArgs&&... args) const
            -> decltype(this->func(std::forward<TArgs>(args)...))
    {
        return func(std::forward<TArgs>(args)...);
    }
};

So the 2) that you term as a drawback of your workaround is not actually a drawback because the real way to code this still needs the member to be declare before you use it.

like image 30
Johannes Schaub - litb Avatar answered Sep 29 '22 23:09

Johannes Schaub - litb