代码的目的是找到32位浮点位模式的总数,它代表0到1之间的值.在我看来这应该可行,但由于某种原因,Clang的汇编输出基本上相当于return 0;.
我使用-std=c++1y -Wall -Wextra -pedantic -O2和编译了Clang 3.3和Clang 3.4.1-std=c++1y -Wall -Wextra -pedantic -O3
Clang 3.4使用-O2和-O3优化一切.
Clang 3.3仅使用-O3优化一切.
通过"优化一切",我的意思是这是程序的汇编输出:
main: # @main
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
#include <limits>
#include <cstring>
#include <cstdint>
template <class TO, class FROM>
inline TO punning_cast(const FROM &input)
{
TO out;
std::memcpy(&out, &input, sizeof(TO));
return out;
}
int main()
{
uint32_t i = std::numeric_limits<uint32_t>::min();
uint32_t count = 0;
while (1)
{
float n = punning_cast<float>(i);
if(n >= 0.0f && n <= 1.0f) …Run Code Online (Sandbox Code Playgroud) 有时将复杂或长表达式分成多个步骤是明智的(例如,第二个版本不是更清楚,但它只是一个例子):
return object1(object2(object3(x)));
Run Code Online (Sandbox Code Playgroud)
可以写成:
object3 a(x);
object2 b(a);
object1 c(b);
return c;
Run Code Online (Sandbox Code Playgroud)
假设所有3个类都实现了以rvalue作为参数的构造函数,第一个版本可能更快,因为临时对象被传递并可以移动.我假设在第二个版本中,局部变量被认为是左值.但是如果以后没有使用变量,那么C++ 11编译器是否会优化代码,因此变量被认为是rvalues,两个版本的工作方式完全相同?我最感兴趣的是Visual Studio 2013的C++编译器,但我也很高兴知道GCC编译器在这个问题上的行为.
谢谢,米哈尔
我已经看到它说一个operator=带有相同类型by-value的参数的文件在C++ 11中既作为复制赋值运算符又作为移动赋值运算符:
Foo& operator=(Foo f)
{
swap(f);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
替代方案的重复次数将超过两倍,并且可能出现错误:
Foo& operator=(const Foo& f)
{
Foo f2(f);
swap(f2);
return *this;
}
Foo& operator=(Foo&& f)
{
Foo f2(std::move(f));
swap(f2);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
在什么情况下,ref-to-const和r-value重载优先通过值,或何时需要?我正在考虑std::vector::push_back,例如,它被定义为两个重载:
void push_back (const value_type& val);
void push_back (value_type&& val);
Run Code Online (Sandbox Code Playgroud)
在第一个示例中,pass by value 用作复制赋值运算符和移动赋值运算符,无法push_back在Standard中定义为单个函数?
void push_back (value_type val);
Run Code Online (Sandbox Code Playgroud) 受此问题的启发,关于编译器是否可以优化掉对函数的调用而没有副作用.假设我有以下代码:
delete[] new char[10];
Run Code Online (Sandbox Code Playgroud)
它没有任何用处.但它有副作用吗?堆分配后立即释放被认为是副作用吗?
如果我使用Clang 3.3编译以下代码,-O3 -fno-vectorize即使删除了注释行,也会得到相同的汇编输出.代码类型将所有可能的32位整数置于浮点数并计算[0,1]范围内的值.Clang的优化器实际上是否足够聪明,以致当被处理为浮点数时0xFFFFFFFF不在[0,1]的范围内,所以忽略fn完全的第二次调用?删除第二个调用时,GCC会生成不同的代码.
#include <limits>
#include <cstring>
#include <cstdint>
template <class TO, class FROM>
inline TO punning_cast(const FROM &input)
{
TO out;
std::memcpy(&out, &input, sizeof(TO));
return out;
}
int main()
{
uint32_t count = 0;
auto fn = [&count] (uint32_t x) {
float f = punning_cast<float>(x);
if (f >= 0.0f && f <= 1.0f)
count++;
};
for(uint32_t i = 0; i < std::numeric_limits<uint32_t>::max(); ++i)
{
fn(i);
}
fn(std::numeric_limits<uint32_t>::max()); //removing this changes nothing
return count;
}
Run Code Online (Sandbox Code Playgroud)
见这里: …
我想为某个类型实现移动构造函数(没有复制构造函数),该类型需要是一个值类型boost::unordered_map.我们称之为这种类型Composite.
Composite 有以下签名:
struct Base
{
Base(..stuff, no default ctor) : initialization list {}
Base(Base&& other) : initialization list {}
}
struct Composite
{
Base member;
Composite(..stuff, no default ctor) : member(...) {}
Composite(Composite&& other) : member(other.member) {} // <---- I want to make sure this invokes the move ctor of Base
}
Run Code Online (Sandbox Code Playgroud)
我想写这个,所以boost::unordered_map< Key , Composite >不需要复制构造函数,只需使用移动构造函数.如果可能的话,我不想Base在移动构造函数的初始化列表中使用复制构造函数Composite.
这可能吗?
最近我看到了几个这样的代码示例,其中std :: move用于构造函数初始化列表(不是移动构造函数).
class A {
public:
A(std::shared_ptr<Res> res) : myRes(std::move(res)) {
// ...
}
private:
std::shared_ptr<Res> myRes;
}
Run Code Online (Sandbox Code Playgroud)
我得到的信息是这个结构是出于优化原因.我个人使用std :: move尽可能少见.我威胁他们作为演员(如Scott Meyers所说),并且只在调用者代码中(只有例外是移动构造函数).对我来说,它看起来像某种混淆或微观优化,但也许我错了.是不是真的,如果没有std :: move,编译器不会产生更快的代码?
示例程序:
#include <iostream>
#include <string>
#include <vector>
template <typename T>
void print(const T& _vec)
{
for( auto c: _vec )
std::cout << c << ",";
}
typedef std::vector<std::string> vecstr_t;
struct Trade
{
explicit Trade(vecstr_t&& vec) : _vec(vec )
{
}
vecstr_t _vec;
};
int main()
{
vecstr_t tmpV = {"ONE", "TWO", "THREE", "FOUR"};
std::cout << "size 1:" << tmpV.size() << "\t"; print(tmpV); std::cout << "\n" ;
Trade t(std::move(tmpV));
std::cout << "size 2:" << tmpV.size() << "\t"; print(tmpV); std::cout << "\n" …Run Code Online (Sandbox Code Playgroud) 当 C++ 创建std::ofstream它时,它立即并隐式创建底层文件。
我完全同意这种行为,除非我有一个代码,只有在运行期间才能看到是否会产生任何数据。
因此,我想避免在没有数据发送给空文件时创建空文件(事务完整性:没有数据,文件系统上没有更改)。
我看到两种我不太喜欢的方法:
tellg()),如果流为空,则删除该文件。我不喜欢创建和删除文件(有时文件很多)并且remove操作本身承担了太多责任。std::stringstream,收集输出并std::ofstream仅在字符串流不为空的情况下创建和复制内容。好多了,但仍然需要临时内存分配,这可能很大。对此有更好的解决方案吗?我是否缺少一些想法?
以代码的形式:
#include <fstream>
int main()
{
std::ofstream ofs("file.txt");
// Some code that might or might not output to ofs
// Some other code that might or might not output to ofs
// Some more code that might or might not output to ofs
// It would be nice if file is not created if no data sent to ofs
} …Run Code Online (Sandbox Code Playgroud) c++ ×9
c++11 ×6
clang ×2
move ×2
llvm ×1
memory ×1
optimization ×1
overloading ×1
std ×1
visual-c++ ×1