问题
When I declare a class static method, is it possible to refer current class using decltype
(or in any other similar style)? For example,
class
AAA
{
static AAA const make();
};
I am trying to make something like this.
class
AAA
{
static decltype(*this) const make(); // Not working because there's no `this`.
};
The *this
is used to describe what I want to do. I want to know some decltype()
expression which can be resolved to AAA
.
If it's possible how can I do that?
回答1:
In C++1y you could do this:
class
AAA
{
public:
static auto make()
{
return AAA();
}
};
int main()
{
AAA aaa = AAA::make();
}
This is not legal in C++11 as you need to specify a return type for make()
. In C++98/03/11 you can:
class
AAA
{
public:
typedef AAA Self;
static Self make()
{
return AAA();
}
};
That is low-tech, but very readable.
<aside>
You should avoid returning const-qualified types by value. This inhibits efficient move semantics. If you want to avoid assigning to rvalues, then create an assignment operator qualified with &
.
</aside>
回答2:
You could perhaps do something like this:
#include<iostream>
class AAA
{
int _i;
public:
AAA(int i): _i(i) {}
static auto make(int i) -> typename std::remove_reference<decltype(*this)>::type
{
return {i};
}
void print()
{
std::cout << _i << std::endl;
}
};
int main()
{
AAA aaa = AAA::make(1);
aaa.print();
return 0;
}
It compiles on GCC 4.7.2 at least :)
EDIT 26/11-13: The above code is not legal c++, even though it compiles with gcc, it does not with clang or icpc. My apologies.
回答3:
Just invented a way using member pointers, and it seems to work: https://godbolt.org/z/v-g5z0
#define self_test(name) \
void dummy__##name(void) {} \
template static T type__##name( void (T::*func)(void) ) { return T(); } \
typedef decltype(type__##name(&dummy__##name)) self__##name; \
static void test( void ) { self__##name::print(); }
struct T1 {
self_test(X);
static void print() { printf( "this is T1\n" ); }
};
struct T2 {
self_test(X);
static void print() { printf( "this is T2\n" ); }
};
int main() {
T1::test();
T2::test();
}
This is not perfect either, it requires -fpermissive to compile with gcc, but at least gcc/VS/Intel all compile it and it works. Also in fact gcc/mingw doesn't even require -fpermissive for this.
来源:https://stackoverflow.com/questions/20203640/how-to-refer-current-class-using-decltype-in-c11