小编GMa*_*ckG的帖子

rvalue结构的成员是右值还是左值?

返回结构的函数调用是一个rvalue表达式,但它的成员呢?
这段代码适用于我的g ++编译器,但是gcc给出了一个错误,说"左值作为赋值的左操作数":

struct A
{
    int v;
};

struct A fun()
{
    struct A tmp;
    return tmp;
}

int main()
{
    fun().v = 1;
}
Run Code Online (Sandbox Code Playgroud)

gcc视为fun().v右值,我能理解.
但是g ++并不认为赋值表达式是错误的.这是否意味着fun1().v是C++中的左值?
现在的问题是,我搜索了C++ 98/03标准,没有找到关于fun().v是左值还是左值的说法.
那么,它是什么?

c++ structure rvalue lvalue

26
推荐指数
1
解决办法
2567
查看次数

为什么具有固定底层类型char的枚举值会解析为fct(int)而不是fct(char)?

在回答有关使用枚举的重载解析的问题时,出现了此问题.

虽然案例long long肯定是MSVC2012NovCTP中的一个错误(根据标准文本和gcc 4.7.1的测试),我无法弄清楚为什么会出现以下行为:

#include <iostream>

enum charEnum : char { A = 'A' };

void fct(char)      { std::cout << "fct(char)"      << std::endl; }
void fct(int)       { std::cout << "fct(int)"       << std::endl; }
void fct(long long) { std::cout << "fct(long long)" << std::endl; }

int main() 
{
    fct('A');
    fct(A);
}
Run Code Online (Sandbox Code Playgroud)

MSVC2012NovCTP和gcc 4.7.1都同意此输出:

fct(char)
fct(int)

A应该转换charEnumchar?为什么A被转换成int

编辑:clang抱怨说这个电话含糊不清,这与我在下面的解释一致; 那说,如果它只被认为是潜在的类型,我仍然会发现它更直观.


两个相关的标准摘录是§7.2/ 9:

枚举器的值或未范围的枚举类型的对象通过整数提升转换为整数(4.5)

并且§4.5/ 4:

其底层类型为固定(7.2)的无范围枚举类型的prvalue可以转换为其基础类型的prvalue.此外,如果可以对其基础类型应用整数提升,则其基础类型固定的未范围枚举类型的prvalue也可以转换为提升的基础类型的prvalue.

因此, …

c++ enums overloading overload-resolution c++11

25
推荐指数
1
解决办法
1768
查看次数

不能在数组上使用.begin()或.end()

错误如下:

请求'arr'中的成员'begin','end'是非类型int [5],无法从表达式错误中推断出来.

我的代码:

#include <iostream>
using namespace std;

int main()
{
    int * mypointer;

    int arr[5] = {1,3,5,7,9};

    mypointer = arr;

    for(auto it = arr.begin(); it != arr.end(); ++it) {
        cout<<*mypointer<<endl;

        mypointer++;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ arrays pointers iterator c++11

25
推荐指数
2
解决办法
4万
查看次数

如何组合输出流,以便输出一次多个位置?

我想将两个(或更多)流组合成一个.我的目标是将任何输出定向到cout,cerr并且clog还将其与原始流一起输出到文件中.(例如,当事情记录到控制台时.关闭后,我仍然希望能够返回并查看输出.)

我在考虑做这样的事情:

class stream_compose : public streambuf, private boost::noncopyable
{
public:
    // take two streams, save them in stream_holder,
    // this set their buffers to `this`.
    stream_compose;

    // implement the streambuf interface, routing to both
    // ...

private:
    // saves the streambuf of an ios class,
    // upon destruction restores it, provides
    // accessor to saved stream
    class stream_holder;

    stream_holder mStreamA;
    stream_holder mStreamB;
};
Run Code Online (Sandbox Code Playgroud)

这看起来很简单.然后在main中的调用将是这样的:

// anything that goes to cout goes to both …
Run Code Online (Sandbox Code Playgroud)

c++ boost iostream stream tee

20
推荐指数
3
解决办法
8910
查看次数

基于范围的语句定义冗余

查看n3092,在§6.5.4中,我们找到了基于范围的for循环的等价性.然后它继续说什么__begin__end等于.它区分了数组和其他类型,我觉得这是多余的(也就是令人困惑).

它表示数组类型__begin__end你所期望的:指向第一个的指针和指向一个结尾的指针.那么对于其他类型的,__begin__end等于begin(__range)end(__range),与ADL.命名空间std是关联的,以便在第24.6.5节中找到std::beginstd::end定义<iterator>.

但是,如果我们看的定义std::beginstd::end,他们是阵列以及容器类型都定义.并且数组版本与上面完全相同:指向第一个的指针,指向一个结尾的指针.

为什么需要将数组与其他类型区分开来,当为其他类型提供的定义同样适用时,查找std::beginstd::end


为方便起见,有些删节报价:

§6.5.4基于范围的for陈述

- 如果_RangeT是一个数组类型,则begin-expr和end-expr分别是__range和__range + __bound,其中__bound是数组绑定的.如果_RangeT是未知大小的数组或不完整类型的数组,则程序格式错误.

- 否则,begin-expr和end-expr分别是begin(__ range)和end(__ range),其中begin和end通过参数依赖查找(3.4.2)查找.出于此名称查找的目的,名称空间std是关联的名称空间.

§24.6.5范围访问

template <class T, size_t N> T* begin(T (&array)[N]);
Run Code Online (Sandbox Code Playgroud)

返回:数组.

template <class T, size_t N> T* end(T (&array)[N]);
Run Code Online (Sandbox Code Playgroud)

返回:数组+ N.

c++ for-loop range argument-dependent-lookup c++11

19
推荐指数
1
解决办法
3459
查看次数

是否可以避免在实现文件中重复类名?

有没有办法避免Graph::实现文件中的重复,但仍然将类拆分为头+实现?如:

头文件:

#ifndef Graph_H
#define Graph_H

class Graph {
public:
    Graph(int n);
    void printGraph();
    void addEdge();
    void removeEdge();
};

#endif
Run Code Online (Sandbox Code Playgroud)

实施档案:

Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}
Run Code Online (Sandbox Code Playgroud)

c++ syntax class

19
推荐指数
4
解决办法
5398
查看次数

有没有人有使用gcc的LTO(C++)的经验?

我的主要兴趣是将代码从头文件移动到源文件(用于解耦),但保持内联内容的相同性能.

我不知道从哪里开始,有人可以解释该怎么做?

c++ gcc

18
推荐指数
2
解决办法
3766
查看次数

C++"从容器中移出"

在C++ 11中,std::move当我们想要将值移动(破坏性地复制)到容器中时,我们可以提高效率:

SomeExpensiveType x = /* ... */;
vec.push_back(std::move(x));
Run Code Online (Sandbox Code Playgroud)

但我找不到任何其他方式.我的意思是这样的:

SomeExpensiveType x = vec.back(); // copy!
vec.pop_back(); // argh
Run Code Online (Sandbox Code Playgroud)

这在适配器上更常见(copy-pop)stack.可能存在这样的事情:

SomeExpensiveType x = vec.move_back(); // move and pop
Run Code Online (Sandbox Code Playgroud)

为了避免副本?这已经存在了吗?我在n3000中找不到类似的东西.

我有一种感觉,我错过了一些非常明显的东西(比如它的不必要),所以我准备好了"ru dum".:3

c++ containers rvalue-reference c++11

18
推荐指数
1
解决办法
3281
查看次数

空白的C转义序列是什么?

我正在编写一个程序来计算空格,制表符和换行符.我记得标签和换行符的转义序列是什么,但空白呢?\ B' 还是那个退格?

c escaping

17
推荐指数
3
解决办法
6万
查看次数

如何将智能指针传递给函数?

将对象传递给函数时,相同的规则是否适用于智能指针以及包含动态内存的其他对象?

例如,当我传递std::vector<std::string>给函数时,我总是考虑以下选项:

  1. 我将改变矢量对象的状态,但我希望在函数完成后反映这些更改,AKA进行复制.

    void function(std::vector<std::string> vec);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我要改变矢量对象的状态,我确实希望在函数完成后反映这些更改,AKA做出参考.

    void function(std::vector<std::string> & vec);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 这个对象非常大,所以我最好传递一个引用,但是告诉编译器不要让我改变它.

    void function(std::vector<std::string> const& vec);  
    
    Run Code Online (Sandbox Code Playgroud)

现在这与智能指针的逻辑相同吗?什么时候应该考虑移动语义?关于如何通过智能指针的一些指导是我最想要的.

c++ smart-pointers parameter-passing unique-ptr c++11

17
推荐指数
3
解决办法
2万
查看次数