返回结构的函数调用是一个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是左值还是左值的说法.
那么,它是什么?
在回答有关使用枚举的重载解析的问题时,出现了此问题.
虽然案例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应该转换charEnum为char?为什么A被转换成int?
编辑:clang抱怨说这个电话含糊不清,这与我在下面的解释一致; 那说,如果它只被认为是潜在的类型,我仍然会发现它更直观.
两个相关的标准摘录是§7.2/ 9:
枚举器的值或未范围的枚举类型的对象通过整数提升转换为整数(4.5)
并且§4.5/ 4:
其底层类型为固定(7.2)的无范围枚举类型的prvalue可以转换为其基础类型的prvalue.此外,如果可以对其基础类型应用整数提升,则其基础类型固定的未范围枚举类型的prvalue也可以转换为提升的基础类型的prvalue.
因此, …
错误如下:
请求'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) 我想将两个(或更多)流组合成一个.我的目标是将任何输出定向到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) 查看n3092,在§6.5.4中,我们找到了基于范围的for循环的等价性.然后它继续说什么__begin和__end等于.它区分了数组和其他类型,我觉得这是多余的(也就是令人困惑).
它表示数组类型__begin和__end你所期望的:指向第一个的指针和指向一个结尾的指针.那么对于其他类型的,__begin并__end等于begin(__range)和end(__range),与ADL.命名空间std是关联的,以便在第24.6.5节中找到std::begin并std::end定义<iterator>.
但是,如果我们看的定义std::begin和std::end,他们是阵列以及容器类型都定义.并且数组版本与上面完全相同:指向第一个的指针,指向一个结尾的指针.
为什么需要将数组与其他类型区分开来,当为其他类型提供的定义同样适用时,查找std::begin和std::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范围访问
Run Code Online (Sandbox Code Playgroud)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]);返回:数组+ N.
有没有办法避免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++ 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
我正在编写一个程序来计算空格,制表符和换行符.我记得标签和换行符的转义序列是什么,但空白呢?\ B' 还是那个退格?
将对象传递给函数时,相同的规则是否适用于智能指针以及包含动态内存的其他对象?
例如,当我传递std::vector<std::string>给函数时,我总是考虑以下选项:
我将改变矢量对象的状态,但我不希望在函数完成后反映这些更改,AKA进行复制.
void function(std::vector<std::string> vec);
Run Code Online (Sandbox Code Playgroud)我要改变矢量对象的状态,我确实希望在函数完成后反映这些更改,AKA做出参考.
void function(std::vector<std::string> & vec);
Run Code Online (Sandbox Code Playgroud)这个对象非常大,所以我最好传递一个引用,但是告诉编译器不要让我改变它.
void function(std::vector<std::string> const& vec);
Run Code Online (Sandbox Code Playgroud)现在这与智能指针的逻辑相同吗?什么时候应该考虑移动语义?关于如何通过智能指针的一些指导是我最想要的.