Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用C++;使用重载运算符++;(增薪前)_C++_Operator Overloading_C++11_Decltype - Fatal编程技术网

C++ 使用C++;使用重载运算符++;(增薪前)

C++ 使用C++;使用重载运算符++;(增薪前),c++,operator-overloading,c++11,decltype,C++,Operator Overloading,C++11,Decltype,对于某些模板typename,我想创建一个typedef,它是T::operator++()(也称为T的预增量运算符)的声明返回类型 我没有在网上找到任何明确的信息,尽管肯定有人提到decltype和preincrement。所以我尝试了一些方法,唯一一个真正有效的方法似乎是一个肮脏的黑客。你觉得这个怎么样 struct S { // dummy type to simulate a real one I have int operator++() { return 0; } // no

对于某些模板typename,我想创建一个typedef,它是T::operator++()(也称为T的预增量运算符)的声明返回类型

我没有在网上找到任何明确的信息,尽管肯定有人提到decltype和preincrement。所以我尝试了一些方法,唯一一个真正有效的方法似乎是一个肮脏的黑客。你觉得这个怎么样

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;
}
我使用的是GCC4.6.2。我曾短暂尝试过Clang,但效果并不好。

对于临时类型,内置类型和用户定义类型的左值不同:在您的示例中,临时
int
是右值,而临时
S
是左值

编辑:从技术上讲,所有临时变量都是右值,但运算符对用户定义类型的处理方式不同,因为它们实际上是伪装的常规函数。这意味着您可以使用它们做一些非右值的事情,例如将
S()
作为默认赋值运算符的左侧

用于获取非计算上下文中任意类型的左值或右值:

#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&
#包括
//declval产生一个左值,declval产生一个右值
typedef decltype(std::declval()++)T1;//int
typedef decltype(++std::declval())T2;//int&
typedef decltype(std::declval()++)T3;//s
typedef decltype(++std::declval())T4;//&
对于临时变量,内置类型和用户定义类型的左值不同:在您的示例中,临时
int
是右值,而临时
S
是左值

编辑:从技术上讲,所有临时变量都是右值,但运算符对用户定义类型的处理方式不同,因为它们实际上是伪装的常规函数。这意味着您可以使用它们做一些非右值的事情,例如将
S()
作为默认赋值运算符的左侧

用于获取非计算上下文中任意类型的左值或右值:

#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&
#包括
//declval产生一个左值,declval产生一个右值
typedef decltype(std::declval()++)T1;//int
typedef decltype(++std::declval())T2;//int&
typedef decltype(std::declval()++)T3;//s
typedef decltype(++std::declval())T4;//&

这很有趣,但declval并非在我所关心的所有平台上都可用(例如Boost 1.45和GCC 4.4)。我可以通过复制/粘贴Boost所拥有的东西来实现它,但是它会相当长且难看,不比
decltype(+++*(S*)nullptr)
@JohnZwinck好。你最好把
*(S*)nullptr
放到一个函数中,然后调用
declval
。我不知道最近的Boost做了什么(比如变通方法),但这基本上就是它应该做的。@Johannes-你当然是绝对正确的<代码> S-():/Cux>不是C++标准意义下的LValk(在C++ 11中,它是一个PROVE值)。但是,考虑到成员函数调用C++的方式,()>代码>可能出现在内置类型需要LValue-最重要的是,作为默认赋值操作符的左手边的上下文中。但declval并非在我关心的所有平台上都可用(例如Boost 1.45和GCC 4.4)。我可以通过复制/粘贴Boost所拥有的东西来实现它,但是它会相当长且难看,不比
decltype(+++*(S*)nullptr)
@JohnZwinck好。你最好把
*(S*)nullptr
放到一个函数中,然后调用
declval
。我不知道最近的Boost做了什么(比如变通方法),但这基本上就是它应该做的。@Johannes-你当然是绝对正确的<代码> S-():/Cux>不是C++标准意义下的LValk(在C++ 11中,它是一个PROVE值)。但是,考虑到成员函数调用C++的方式,()>代码>可能出现在构建类型需要LValue-最重要的上下文中,作为default assignment operator.FWIW的左侧,您无法使用
++
表达式上的
decltype
来获取声明的返回类型-它过去适用于某些C++11草案,但已发布的规范不再适用于此。因此,如果您声明一个返回类型
int-const
decltype
将为您提供的仍然是
int
,而不是
int-const
。虽然除了这个人工示例之外,我还不知道获取声明的返回类型和表达式的类型(发布的规范生成)之间有什么真正的区别。我可以接受这一点。感谢您的清晰解释。FWIW您无法使用
++
表达式上的
decltype
来获取声明的返回类型-它过去适用于某些C++11草案,但已发布的规范不再适用于此。因此,如果您声明一个返回类型
int-const
decltype
将为您提供的仍然是
int
,而不是
int-const
。虽然除了这个人工示例之外,我还不知道获取声明的返回类型和表达式的类型(发布的规范生成)之间有什么真正的区别。我可以接受这一点。谢谢你的清楚解释。