在成员函数尾部返回类型中使用this和属性

Using this and attributes in member function trailing return types?

本文关键字:this 属性 成员 函数 尾部 返回类型      更新时间:2023-10-16

在我给出的这个答案中,在后面的返回类型中使用this和类_arg的属性作为decltype表达式的一部分是有意义的。没有可能,但不方便。

clang 3.0(见下文)和gcc 4.5.2都没有接受它。

#include <iostream>
class MyClass {
public:
  MyClass(int i): _arg(i) {}
  template <typename F>
  auto apply(F& f) -> decltype(f(_arg)) {
    return f(_arg);
  }
  template <typename F>
  auto apply(F& f) -> decltype(f(*this, _arg)) {
    return f(*this, _arg);
  }
private:
  int _arg;
};
struct Id {
  template <typename V>
  V operator()(V v) const { return v; }
};
struct ComplexId {
  template <typename C, typename V>
  V operator()(C const&, V v) { return v + 1; }
};
int main() {
  Id id; ComplexId complex;
  MyClass c(0);
  std::cout << c.apply(id) << " " << c.apply(complex) << "n";
}

clang 3.0说:

$ clang++ -std=c++11 -Weverything test.cpp
test.cpp:8:38: error: use of undeclared identifier '_arg'
      auto apply(F& f) -> decltype(f(_arg)) {
                                     ^
test.cpp:8:45: error: type name requires a specifier or qualifier
      auto apply(F& f) -> decltype(f(_arg)) {
                                            ^
test.cpp:8:45: error: C++ requires a type specifier for all declarations
      auto apply(F& f) -> decltype(f(_arg)) {
                          ~~~~~~~~          ^
test.cpp:8:7: error: 'auto' return without trailing return type
      auto apply(F& f) -> decltype(f(_arg)) {
      ^
test.cpp:13:39: error: invalid use of 'this' outside of a nonstatic member function
      auto apply(F& f) -> decltype(f(*this, _arg)) {
                                      ^
test.cpp:13:52: error: type name requires a specifier or qualifier
      auto apply(F& f) -> decltype(f(*this, _arg)) {
                                                   ^
test.cpp:13:52: error: C++ requires a type specifier for all declarations
      auto apply(F& f) -> decltype(f(*this, _arg)) {
                          ~~~~~~~~                 ^
test.cpp:13:7: error: 'auto' return without trailing return type
      auto apply(F& f) -> decltype(f(*this, _arg)) {
      ^
8 errors generated.

哼。。。不太好。

然而,在大多数编译器中,对C++11的支持充其量是很粗糙的,我在标准(n3290)中找不到具体的限制。

Xeo在评论中表示,这可能是标准中的一个缺陷。。。

那么,这是允许还是不允许

奖金:clang/gcc的最新版本支持这一点吗

我记错了。这在某种程度上是一个缺陷,但最终得到了解决,并被投票加入了FDIS。

§5.1.1 [expr.prim.general]

如果声明声明了类X的成员函数或成员函数模板,则表达式this是介于可选的cv限定符seq函数定义成员声明符声明符末尾之间的类型为"指向cv限定符seqX的指针"的prvalue。

因此,Clang和GCC还没有正确地实现它。

struct X{
  // 'this' exists between the | markers
  void f() const volatile | {
  } |
  auto g() const volatile | -> void {
  } |
};

您的代码无效的C++11,因为该类在成员函数的返回类型中不被认为是完整的。您只能访问以前已声明的成员。像这样

class MyClass {
private:
  int _arg;
public:
  MyClass(int i): _arg(i) {}
  template <typename F>
  auto apply(F& f) -> decltype(f(_arg)) {
    return f(_arg);
  }
  template <typename F>
  auto apply(F& f) -> decltype(f(*this, _arg)) {
    return f(*this, _arg);
  }
};

使用this的模块在C++11中的尾部返回类型中是有效的。

我不知道你写的东西是否合法,但还有一些其他方法可以实现你想要的:

  template <typename F>
  auto apply(F& f) -> decltype(f(*(MyClass*)0, (int)0)) {
    return f(*this, _arg);
  }

或者:

  template <typename F>
  typename std::result_of<F(MyClass,int)>::type apply(F& f) {
    return f(*this, _arg);
  }