Using this and attributes in return types of member function returns?

In this answer I gave, it makes sense to use this and the class attribute _arg in the return type as part of decltype . You can do without, but uncomfortable.

Neither clang 3.0 (see below) nor gcc 4.5.2 accepted it.

 #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 says:

 $ 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. 

Hmm ... not so great.

However, C ++ 11 support in most compilers is a hack, and I could not find the specific limitations mentioned in the standard (n3290).

In the comments, Xeo suggested that it could be a defect in the standard ...

So is it allowed or not?

Bonus: and are you running the latest clang / gcc support?

+6
source share
3 answers

I forgot. It was a defect at some point , but eventually resolved and voted in FDIS .

Β§5.1.1 [expr.prim.general]

If the declaration declares a member template or template of a member function of class X , the this expression is a value of the type "pointer to cv-qualifier-seq X " between the optional cv-qualifer-seq and the end of the description of the function, member declaration or declarator.

Thus, Clang and GCC just do not implement it correctly.

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

Your code is invalid C ++ 11 because the class is not considered complete in the return type of the member function. You can only access those previously announced. Thus

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

Modulo, yes, using this , let's say in C ++ 11 in the return type.

+5
source

I don’t know if what you are writing is legal, but there are other ways to achieve what you want:

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

Or:

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

Source: https://habr.com/ru/post/906937/


All Articles