让我们在一个示例中展示它,其中我们有一个包含主数据的 Data 类、某种指向主数据的索引,并且我们还需要公开索引const的版本。
class Data
{
public:
const std::vector<int>& getPrimaryData() const { return this->primaryData; }
const std::vector<int*>& getIndex() const { return this->index; }
private:
std::vector<int> primaryData;
std::vector<int*> index;
};
Run Code Online (Sandbox Code Playgroud)
这是错误的,因为用户可以轻松修改数据:
const Data& data = something.getData();
const std::vector<int*>& index = data.getIndex();
*index[0] = 5; // oups we are modifying data of const object, this is wrong
Run Code Online (Sandbox Code Playgroud)
原因是 Data::getIndex 应返回的正确类型是:
const std::vector<const int*>&
Run Code Online (Sandbox Code Playgroud)
但是您可以猜测当您尝试以“仅将非常量变体转换为常量变体”的方式编写方法时会发生什么:
// compiler error, can't convert std::vector<int*> to std::vector<const int*> these are unrelated types.
const std::vector<const int*>& …Run Code Online (Sandbox Code Playgroud) 我们有一个需要确定性的游戏,因为它是多人游戏模型的一部分.我们还使用Lua,它在sprintf内部使用(格式为%.14g).
打印数字如0.00001时会出现问题.在某些情况下,它会打印1e-05,在某些情况下,它会打印1e-005(额外为零).
例如,当使用Visual Studio 2015进行编译时,它会进行打印1e-005,并使用Visual Studio 2013进行打印1e-05.我尝试了不同的区域设置,但似乎没有任何效果.
问题是:实现确定性结果的最佳解决方案是什么? 我不关心科学记谱法是否标准化或消除.
我想到的解决方案:
%f符号时,它不会忽略无关紧要的零,因此%.14f会导致不切实际的长数.sprintf方法(从某些标准库粘贴的副本)标题是不言自明的,输入给出双倍值,我想添加/减少可能的最小量.
我正在使用C++环境,并且:
a)我们被禁止使用异常
b)应用程序/数据服务器代码可以评估不同种类的请求
我有简单的类封装服务器操作的结果,也在内部用于那里的许多功能.
class OpResult
{
.....
bool succeeded();
bool failed(); ....
... data error/result message ...
};
Run Code Online (Sandbox Code Playgroud)
当我试图让所有函数变得小而简单时,会产生很多这样的块:
....
OpResult result = some_(mostly check)function(....);
if (result.failed())
return result;
...
Run Code Online (Sandbox Code Playgroud)
问题是,让宏看起来像这样并在任何地方使用它是不好的做法吗?
#define RETURN_IF_FAILED(call) \
{ \
OpResult result = call; \
if (result.failed()) \
return result; \
}
Run Code Online (Sandbox Code Playgroud)
我知道有人可以称之为讨厌,但有更好的方法吗?你会建议用什么其他方法来处理结果并避免大量的膨胀代码?
我需要能够保存/加载这个boost随机生成器的状态:
boost::variate_generator<boost::mt19937, boost::random::uniform_real_distribution<> > generator;
Run Code Online (Sandbox Code Playgroud)
我是这样做的:
std::ostringstream content;
content << this->generator.engine();
Run Code Online (Sandbox Code Playgroud)
问题是,这是非常慢,是不是有一些替代方式来存储它?(或以原生格式访问随机生成器数据).这段代码封装在我们的RandomGenerator类中,所以它可能有点讨厌.
我需要在C++中实现工厂类,但是当我考虑这个时,我发现了一个我无法解决的大问题,并且我发现,所有工厂实现示例都以同样的方式存在缺陷.我可能是那个错了,但请告诉我原因.
所以这里是简单的"典型"工厂实现,它允许我在不更改Factory类的情况下注册新对象.
//fruit.h
class Fruit
{
protected :
int count;
public :
Fruit(int count) : count(count) {}
virtual void show() = 0;
};
// factory.h
/** singleton factory */
class Factory
{
typedef Fruit* (*FruitCreateFunction)(int);
static Factory* factory;
std::map<std::string, FruitCreateFunction> registeredFruits;
public :
static Factory& instance()
{
if (factory == NULL)
factory = new Factory();
return *factory;
}
bool registerFruit(const std::string& name, Fruit* (createFunction)(int))
{
registeredFruits.insert(std::make_pair(name, createFunction));
return true;
}
Fruit* createFruit(const std::string& name, int count)
{
return registeredFruits[name](count);
} …Run Code Online (Sandbox Code Playgroud) boost文档(http://www.boost.org/doc/libs/1_55_0/doc/html/intrusive.html)指出侵入式容器是为list(单/双链接)set和multiset.我找不到地图的实现.有没有更深层次的理由,还是只是等待实施?
我需要解析unicode参数,所以我想改用wmain.
而不是
int main(int argc, char** argv)
Run Code Online (Sandbox Code Playgroud)
我想用
int wmain(int argc, wchar_t** argv)
Run Code Online (Sandbox Code Playgroud)
问题是视觉工作室没有识别出wmain,而是试图使用main代替:
error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
Run Code Online (Sandbox Code Playgroud)
这是我试过的:
更改入口点(在这种情况下,我对甚至没有入口点的库有很多兼容性错误,因此无法在那里指定).
warning LNK4258: directive '/ENTRY:mainCRTStartup' not compatible with switch '/ENTRY:mainWCRTStartup'; ignored
Run Code Online (Sandbox Code Playgroud)试了一下_tmain,只是为了发现它只是一个将它改为main的宏.
什么都没有帮助.
编辑:我想提一下,我正在使用vs120_xp(Win xp兼容)工具集,但是当我尝试使用默认工具集时,它仍然无效.
编辑2:我试图制作全新的项目,并且wmain在开箱即用.我没有必要改变任何东西,所以它必须是当前项目中导致它的一些特定设置.
我正在寻找一个解决方案,以避免在git中从分支移动到分支时进行大量重新编译.为不同的分支使用不同的文件夹是解决方案,但它只是在我的工作流程中创建了混乱.
我能想到的最好的解决方案是将git分支作为项目设置中使用的选项$变量传递,因此我可以将"输出目录"设置为类似
..\bin\$(branch)\$(Configuration)$(Platform)\
Run Code Online (Sandbox Code Playgroud)
与中间目录类似.
这样的事情可以配置吗?
编辑:问题是,即使每个分支的输出/中间目录不同(或在更改分支时从存档移动),仍然会重新编译预编译的头文件,因此项目也会重新编译.
在我们的应用程序中,我们将任何崩溃记录到包含堆栈跟踪的日志文件中.我们可以使用这些报告来确定崩溃原因.
问题是,我们倾向于在几个地方(实际上很多)捕获std :: exception,这使得在抛出bad_alloc时报告实际上没用,因为堆栈跟踪丢失了.
如何更改行为,所以程序中止而不是抛出bad_alloc?当我们在3个不同的操作系统中编写时,使用3个不同的std实现,改变std本身是我们想要避免的.
从C++ 11开始,我们有这个很棒的功能,它允许我们避免为所有小类创建显式构造函数,例如:
class A
{
public:
A() = default;
A(int x, int y) : x(x), y(y) {} // bloat
int x = 0, y = 0;
};
..
A a(1,2);
Run Code Online (Sandbox Code Playgroud)
所以我们现在可以这样写:
class A
{
public:
int x = 0, y = 0;
};
..
A a{1,2}; // using the sequence constructor created by the compiler, great
Run Code Online (Sandbox Code Playgroud)
问题出现了,当我还有其他我想要使用的构造函数时,例如:
class A
{
public:
A() = default;
A(Deserialiser& input) : a(input.load<int>()), b(input.load<int>()) {}
int x = 0, y = 0;
};
...
A …Run Code Online (Sandbox Code Playgroud) 我总是希望它的工作原理如下所示:"x = x ++"后的x是什么?
但是当我试图测试它时:
int x = 0;
x = x++;
printf("x = %d\n", x);
Run Code Online (Sandbox Code Playgroud)
结果不是我想象的那样但是1.我们在VS2012和g ++(版本4.7)中测试了它.
请注意,此代码按预期打印0:
int x = 0;
int y = x++;
printf("y = %d\n", y);
Run Code Online (Sandbox Code Playgroud) c++ ×11
boost ×2
bad-alloc ×1
c++11 ×1
compilation ×1
constructor ×1
default ×1
double ×1
exception ×1
expression ×1
factory ×1
git ×1
git-branch ×1
lua ×1
map ×1
operators ×1
printf ×1
random ×1
refactoring ×1
singleton ×1
state ×1
stream ×1
unicode ×1
wmain ×1