使用带有重载操作符++的c++ decltype(预增量)

Using C++ decltype with overloaded operator++ (preincrement)

本文关键字:decltype c++ 重载 操作符      更新时间:2023-10-16

对于某些模板typename,我想创建一个typedef,它是T::operator++()(又名T的预增量操作符)声明的返回类型。

我在网上没有找到任何明确的内容,尽管确实有一些提到了带有预增量的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,但也好不到哪里去。

内置类型和用户定义类型的左值在临时类型的情况下是不同的:在您的示例中,临时int是右值,但临时S是左值

编辑:从技术上讲,所有临时值都是右值,但操作符与用户定义类型的工作方式不同,因为它们实际上是伪装的常规函数。这意味着您可以使用它们做一些非右值的事情,例如将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&