For some template typename, I want to make a typedef which is the declared return type of T::operator++() (aka T’s preincrement operator).
I didn’t find anything definitive online, though there are certainly some mentions of decltype with preincrement. So I tried a few things, and the only one which really works seems like a dirty hack. What do you think of this?
struct S { // dummy type to simulate a real one I have
int operator++() { return 0; } // note: return type is not S&
int operator++(int) { return 0; }
};
int main() {
// this works:
typedef decltype(++S()) T1;
// so why doesn't this work?
// error: lvalue required as increment operand
// typedef decltype(++int()) T2;
// this works, but seems dirty:
typedef decltype(++*(int*)nullptr) T3;
typedef decltype(++*(S*)nullptr) T4;
// I also haven't figured out how to disambiguate this,
// though it's moot because int::operator++ is not a thing
// error: ‘S::operator++’ refers to a set of overloaded functions
// typedef decltype(S::operator++) T5;
}
I’m using GCC 4.6.2. I briefly tried Clang but it was no better.
The lvalueness of builtin and user-defined types differs in the case of temporaries: a temporaryintin your example is an rvalue, but a temporarySis an lvalue.Edit: Technically, all temporaries are rvalues, but operators work differently with user-defined types because they are actually regular functions in disguise. This means you can do some rather non-rvalue-like things with them, such as having an
S()as the left-hand side of the default assignment operator!Use
declvalto get an lvalue or rvalue of an arbitrary type in a non-evaluated context: