这是一个开放式的问题.有效的C++.第3项.尽可能使用const.真?
I would like to make anything which doesn't change during the objects lifetime const. But const comes with it own troubles. If a class has any const member, the compiler generated assignment operator is disabled. Without an assignment operator a class won't work with STL. If you want to provide your own assignment operator, const_cast is required. That means more hustle and more room for error. How often you use const class members?
编辑:作为一项规则,我努力保持const的正确性,因为我做了很多多线程.我很少需要为我的类实现复制控制,从不编写删除代码(除非绝对必要).我觉得const的当前状态与我的编码风格相矛盾.Const迫使我实现赋值运算符,即使我不需要它.即使没有const_cast分配也很麻烦.您需要确保所有const成员比较相等,然后手动复制所有非const成员. …
我有一些小但经常使用的函数对象.每个线程都有自己的副本.一切都是静态分配的.副本不共享任何全局或静态数据.我是否需要保护此对象免遭错误共享?
谢谢.编辑:这是一个使用Boost.Threads的玩具程序.字段数据可能会发生错误共享吗?
#include <boost/thread/thread.hpp>
struct Work {
void operator()() {
++data;
}
int data;
};
int main() {
boost::thread_group threads;
for (int i = 0; i < 10; ++i)
threads.create_thread(Work());
threads.join_all();
}
Run Code Online (Sandbox Code Playgroud) 在我的平台上打印9223372036854775808.
double x = 1e19;
std::cout << static_cast<unsigned __int64>(x) << '\n';
Run Code Online (Sandbox Code Playgroud)
我尝试了Boost.NumericConversion,但得到了相同的结果.
将x分成2个相等的部分,然后将转换后的一半加在一起得到正确的结果.但我需要在模板代码中使用通用解决方案.
先感谢您.
编辑:此问题出现在Visual Studio 2008上,但不是MinGW.将4.0e9转换为unsigned long工作正常.
我需要迅速否定大量的双打.如果bit_generator生成0,则必须更改符号.如果bit_generator生成1,则没有任何反应.循环运行多次,bit_generator非常快.在我的平台上,案例2明显快于案例1.看起来我的CPU不喜欢分支.有没有更快,更便携的方式来做到这一点?您如何看待案例3?
// generates 0 and 1
int bit_generator();
// big vector (C++)
vector<double> v;
// case 1
for (size_t i=0; i<v.size(); ++i)
if (bit_generator()==0)
v[i] = -v[i];
// case 2
const int sign[] = {-1, 1};
for (size_t i=0; i<v.size(); ++i)
v[i] *= sign[bit_generator()];
// case 3
const double sign[] = {-1, 1};
for (size_t i=0; i<v.size(); ++i)
v[i] *= sign[bit_generator()];
// case 4 uses C-array
double a[N];
double number_generator(); // generates doubles
double …
Run Code Online (Sandbox Code Playgroud) 你如何复制STL容器?
// big containers of POD
container_type<pod_type> source;
container_type<pod_type> destination
// case 1
destination = source;
// case 2
destination.assign(source.begin(), source.end());
// case 3 assumes that destination.size() >= source.size()
copy(source.begin(), source.end(), destination.size());
Run Code Online (Sandbox Code Playgroud)
我尽可能使用案例1.案例2适用于不同类型的容器.当目标大于源并且您想要保留其余元素时,需要使用案例3.
但是具有非零构造/破坏成本的非POD元素呢?案例3可以胜过案例2吗?如果目标大于源,则实现可能会发生意外情况.这就是Visual Studio 2008在案例2中所做的工作.
GCC 4.5做得更好.源的所有元素都通过赋值复制,然后销毁目标的额外元素.使用case 3然后调整大小在两个平台上做同样的事情(除了一个调整大小需要的默认构造函数).这是玩具程序,它显示了我的意思.
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
struct A {
A() { cout << "A()\n"; }
A(const A&) { cout << "A(const A&)\n"; }
A& operator=(const A&) {
cout …
Run Code Online (Sandbox Code Playgroud) 自由函数allocate_shared可以与任何标准兼容分配器一起使用.但是shared_ptr的构造函数和重置方法呢?
template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
template<class Y, class D, class A> void reset(Y * p, D d, A a);
Run Code Online (Sandbox Code Playgroud)
手册说D应该提供一个调用操作符,用于删除指针,A必须是一个标准的兼容分配器.如果是这样,为什么需要D?不能一个一举两得的分配和delocation?您是否认为为每个自定义分配器提供删除器的要求使上述方法几乎无用?当我使用自定义分配器时,我去了allocate_shared.我怎么知道释放自定义分配器分配的内存的正确方法是什么?
编辑:在使用逐字分配器和删除器进行一些实验后,我发现分配器传递给shared_ptr的构造函数和工厂函数allocate_shared仅用于分配shared_ptr的内部结构.allocate_shared从不使用传递的分配器来分配共享对象.我认为增强手册可以解释如何更明确地使用分配器.
我需要一个实用程序来检查标题保护中的冲突.如果实用程序可以检查符号和文件名是否一致(使用正则表达式或其他东西),那将是很好的.
问候,rn141.
编辑:
示例1.断头防护罩.不能防止多重包含.
// my_file1.h
#ifndef my_project_my_file1_h__
#define my_project_my_fil1_h__ // should be my_project_my_file1_h__
// code goes here
#endif
Run Code Online (Sandbox Code Playgroud)
示例2.与上述标题保护冲突.
// my_file2.h
#ifndef my_project_my_file1_h__ // should be my_project_my_file2_h__
#define my_project_my_file1_h__ // should be my_project_my_file2_h__
// code goes here
#endif
Run Code Online (Sandbox Code Playgroud)