C++新函数声明语法中访问this指针

5
当使用新的函数声明语法和decltype时,如何访问成员?似乎无法访问this
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;
};

这会导致编译器错误:

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

我的编译器是 g++ 4.6.2


我的解决方法是声明一个名为 self 的静态成员,类型与类相同,但存在两个问题:

  1. 它不能像 this 那样自动获取CV限定符。
  2. 我必须将成员声明移动到 decltype 的使用之前,否则它无法看到该成员(尽管这似乎更像是编译器的错误)。
2个回答

3

升级到GCC 4.7版本。在您尝试使用它的地方,版本4.6不支持this

另一个问题涵盖了一些可能可以使用的解决方法。


1
我很高兴...这让我开始质疑自己阅读标准文档的能力,而我本来就对此不是很有信心。 - Travis Gockel
@TravisGockel:一般来说,如果您阅读标准文档与GCC(或任何编译器)存在冲突,那么更有可能是编译器的问题,而不是您的阅读理解能力。 - Nicol Bolas

2

你有两个错误。一个错误是你自己发现的。另一个错误是在声明成员之前尝试访问它。在使用之前先声明它(请注意,即使返回类型以尾随方式指定,也不能访问您稍后声明的成员,不同于函数体)。

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)...);
    }
};

因此,您所称的解决方法的缺点中的“2)”实际上并不是一个缺点,因为真正的编码方式仍然需要在使用之前声明成员。

非常好的一点。事实证明,如果我将func的声明放在更高的位置,删除this->并只使用func是可以的。 - Travis Gockel
@Travis 我认为它不会按照你想要的方式“工作”,因为“const”不是以那种方式被尊重的(在工作文件中更改之前,“this”是不允许的,即使没有明确使用也会隐式使用)。禁止使用“this”与在“decltype”中引用非静态数据成员的能力无关。例如,您可以从“main”中说:“decltype(context_binder::func())”,如果“func”是“public”的并且接受零参数调用。在这种情况下,“context_binder::func”的类型为“Func”,而不是“Func const”。 - Johannes Schaub - litb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接