小编kov*_*rex的帖子

从 const 方法返回 std::vector<int*> 时如何传播 const?

让我们在一个示例中展示它,其中我们有一个包含主数据的 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)

c++ const-correctness

36
推荐指数
6
解决办法
3475
查看次数

跨平台/编译器一致的浮点数sprintf

我们有一个需要确定性的游戏,因为它是多人游戏模型的一部分.我们还使用Lua,它在sprintf内部使用(格式为%.14g).

打印数字如0.00001时会出现问题.在某些情况下,它会打印1e-05,在某些情况下,它会打印1e-005(额外为零).

例如,当使用Visual Studio 2015进行编译时,它会进行打印1e-005,并使用Visual Studio 2013进行打印1e-05.我尝试了不同的区域设置,但似乎没有任何效果.

问题是:实现确定性结果的最佳解决方案什么? 我不关心科学记谱法是否标准化或消除.

我想到的解决方案:

  • 当我使用%f符号时,它不会忽略无关紧要的零,因此%.14f会导致不切实际的长数.
  • 使用自定义sprintf方法(从某些标准库粘贴的副本)
  • 使用一些我没想过的特殊格式(我只使用它作为参考:http://www.cplusplus.com/reference/cstdio/printf/)

c++ lua printf string-formatting

32
推荐指数
2
解决办法
4301
查看次数

15
推荐指数
2
解决办法
4952
查看次数

C++代码纯度

我正在使用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)

我知道有人可以称之为讨厌,但有更好的方法吗?你会建议用什么其他方法来处理结果并避免大量的膨胀代码?

c++ error-handling refactoring

10
推荐指数
3
解决办法
857
查看次数

比使用流来节省增强随机生成器状态更快的替代方案

我需要能够保存/加载这个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++ random boost state stream

5
推荐指数
1
解决办法
592
查看次数

Factory类的典型C++实现是否有缺陷?

我需要在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)

c++ singleton factory factory-pattern

4
推荐指数
1
解决办法
3507
查看次数

为什么没有boost :: intrusive :: map?

boost文档(http://www.boost.org/doc/libs/1_55_0/doc/html/intrusive.html)指出侵入式容器是为list(单/双链接)setmultiset.我找不到地图的实现.有没有更深层次的理由,还是只是等待实施?

c++ boost map intrusive-containers

4
推荐指数
1
解决办法
1580
查看次数

如何强制visual studio使用wmain而不是main

我需要解析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的宏.

  • 使用#pragma注释(链接器,"/ SUBSYSTEM:CONSOLE/ENTRY:mainCRTStartup")
  • 使用UNICODE宏

什么都没有帮助.

编辑:我想提一下,我正在使用vs120_xp(Win xp兼容)工具集,但是当我尝试使用默认工具集时,它仍然无效.

编辑2:我试图制作全新的项目,并且wmain在开箱即用.我没有必要改变任何东西,所以它必须是当前项目中导致它的一些特定设置.

c++ unicode visual-studio wmain

4
推荐指数
1
解决办法
2661
查看次数

如何在Visual Studio中设置Output和Intermeidate目录依赖于当前的git分支?

我正在寻找一个解决方案,以避免在git中从分支移动到分支时进行大量重新编译.为不同的分支使用不同的文件夹是解决方案,但它只是在我的工作流程中创建了混乱.

我能想到的最好的解决方案是将git分支作为项目设置中使用的选项$变量传递,因此我可以将"输出目录"设置为类似

..\bin\$(branch)\$(Configuration)$(Platform)\
Run Code Online (Sandbox Code Playgroud)

与中间目录类似.

这样的事情可以配置吗?

编辑:问题是,即使每个分支的输出/中间目录不同(或在更改分支时从存档移动),仍然会重新编译预编译的头文件,因此项目也会重新编译.

git compilation visual-studio git-branch

3
推荐指数
1
解决办法
769
查看次数

如何实现,bad-alloc中止而不是抛出异常

在我们的应用程序中,我们将任何崩溃记录到包含堆栈跟踪的日志文件中.我们可以使用这些报告来确定崩溃原因.

问题是,我们倾向于在几个地方(实际上很多)捕获std :: exception,这使得在抛出bad_alloc时报告实际上没用,因为堆栈跟踪丢失了.

如何更改行为,所以程序中止而不是抛出bad_alloc?当我们在3个不同的操作系统中编写时,使用3个不同的std实现,改变std本身是我们想要避免的.

c++ exception bad-alloc

2
推荐指数
1
解决办法
82
查看次数

当其他构造函数存在时,如何强制创建默认序列构造函数?

从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)

c++ constructor default c++11

2
推荐指数
1
解决办法
106
查看次数

为什么x = x ++; 不像我期望的那样工作?

我总是希望它的工作原理如下所示:"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++ expression operators

0
推荐指数
1
解决办法
197
查看次数