Использование C ++ decltype с перегруженным оператором ++ (preincrement) - PullRequest
1 голос
/ 25 ноября 2011

Для какого-то шаблона 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, но это было не лучше.

1 Ответ

1 голос
/ 25 ноября 2011

Значение встроенных и пользовательских типов отличается в случае временных значений: временное значение int в вашем примере является значением r, а временное значение S является значением l.

Редактировать: Технически все временные значения являются r-значениями, но операторы работают с пользовательскими типами по-разному, потому что они на самом деле являются замаскированными обычными функциями. Это означает, что вы можете делать с ними некоторые вещи, не относящиеся к rvalue, такие как S() в качестве левой части оператора присваивания по умолчанию!

Используйте declval, чтобы получить lvalue или rvalue произвольного типа в не оцененном контексте:

#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&
...