对于某些模板typename,我想创建一个typedef,它是T :: operator ++()的声明返回类型(也就是T的preincrement运算符)。
我没有在网上找到任何确定的内容,尽管肯定会有一些关于prelcrement的decltype的提及。所以我尝试了一些东西,唯一真正有效的东西看起来像是一个肮脏的黑客。你怎么看待这个?
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;
}
我正在使用GCC 4.6.2。我简短地尝试了Clang但是没有更好。
答案 0 :(得分:1)
内置和用户定义类型的左值在临时情况下有所不同:示例中的临时int
是右值,但临时S
是左值。击>
编辑:从技术上讲,所有临时值都是右值,但运算符与用户定义的类型的工作方式不同,因为它们实际上是伪装的常规函数。这意味着你可以用它们做一些非rvalue之类的事情,例如将S()
作为默认赋值运算符的左侧!
使用declval
在非评估的上下文中获取任意类型的左值或右值:
#include <utility>
// declval<T&> yields an lvalue, declval<T> an rvalue
typedef decltype(std::declval<int&>()++) T1; // int
typedef decltype(++std::declval<int&>()) T2; // int&
typedef decltype(std::declval<S&>()++) T3; // S
typedef decltype(++std::declval<S&>()) T4; // S&