小编ric*_*cab的帖子

链接C++ 17,C++ 14和C++ 11对象是否安全

假设我有三个编译对象,都是由相同的编译器/版本生成的:

  1. A是用C++ 11标准编译的
  2. B是用C++ 14标准编译的
  3. C是用C++ 17标准编译的

为简单起见,我们假设所有头文件都是用C++ 11编写的,只使用其语义在所有三个标准版本之间没有变化的构造,因此任何相互依赖性都用头包含正确表达,编译器没有反对.

这些对象的组合是什么,链接到单个二进制文件是不安全的?为什么?


编辑:欢迎涵盖主要编译器(例如gcc,clang,vs ++)的答案

c++ linker abi c++11 c++14

69
推荐指数
2
解决办法
6748
查看次数

如何让cpack生成正确的开始菜单快捷方式

我想用cmake和cpack为windows上的一些程序创建一个安装程序.我希望能够选择要安装的程序,所选程序将作为快捷方式显示在开始菜单中.这是一个简单的尝试.为每个程序完成了一个组件,但无法弄清楚如何生成开始菜单变量.现在,即使未选择安装它们,所有程序也始终在菜单中.首先是一个简单的程序安装.

#include <iostream>
#include <conio.h>

int main()
{
  std::cout << "prog1" << std::endl;
  _getch();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是CMakeLists.txt文件

cmake_minimum_required( VERSION 2.8 )
project ( CompoTest )

add_executable(prog1 prog1.cpp)
add_executable(prog2 prog2.cpp)
add_executable(prog3 prog3.cpp)

install(TARGETS prog1
        RUNTIME DESTINATION bin
        COMPONENT compo1)
install(TARGETS prog2
        RUNTIME DESTINATION bin
        COMPONENT compo2)
install(TARGETS prog3
        RUNTIME DESTINATION bin
        COMPONENT compo3)

set ( CPACK_PACKAGE_VERSION "1.0.0" )

set(CPACK_PACKAGE_EXECUTABLES 
    prog1 "prog 1"
    prog2 "prog 2"
    prog3 "prog 3"
)

set ( CPACK_COMPONENTS_ALL compo1 compo2 compo3 )
include (CPack)
Run Code Online (Sandbox Code Playgroud)

问题是生成开始菜单快捷方式取决于在安装中选择哪个程序我认为它应该很容易,但似乎不是.是否有可能做到这一点.

更新:我发现 …

c++ nsis cmake cpack

7
推荐指数
1
解决办法
1808
查看次数

没有未定义的行为[c ++],哪些浮点值无法转换为int?

我刚刚从C++ 14标准(我的重点)中读到了这个:

4.9浮动积分转换[conv.fpint]

1浮点类型的prvalue可以转换为整数类型的prvalue.转换截断; 也就是说,丢弃小数部分.如果截断的值无法在目标类型中表示,则行为未定义. [...]

这让我思考

  1. 哪个(如果有的话)floatint在截断后无法表示?(这取决于实施吗?)
  2. 如果有,这是否意味着auto x = static_cast<int>(float)不安全?
  3. 什么是转换的适当/安全的方式floatint然后(假设你要截断)?

c++ type-conversion implicit-conversion c++14

7
推荐指数
2
解决办法
1016
查看次数

我可以添加属性的最常用的python类型是什么?

我有一个类Foo,方法是isValid.然后我有一个方法bar()接收一个Foo对象,其行为取决于它是否有效.

为了测试这个,我想将一些对象传递给bar,其isValid方法总是返回False.由于其他原因,我无法在测试时创建Foo的对象,所以我需要一个对象来伪造它.我首先想到的是创建最通用的对象并向其添加属性isValid,以便将其用作Foo.但那不太奏效:

>>> foo = object()
>>> foo.isValid = lambda : False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'isValid'
Run Code Online (Sandbox Code Playgroud)

我发现对象没有__dict__,所以你不能为它添加属性.此时,我正在使用的解决方法是为此目的动态创建一个类型,然后创建该类型的对象:

>>> tmptype = type('tmptype', (), {'isValid' : lambda self : False})
>>> x = tmptype()
>>> x.isValid()
False
Run Code Online (Sandbox Code Playgroud)

但这似乎太长了一枪.必须有一些随时可用的通用类型,我可以用于此目的,但哪个?

python attributes types object

6
推荐指数
2
解决办法
769
查看次数

C++ - 前向声明和别名(使用using或typedef)

我需要实现以下接口

struct mutex;
struct interface
{
  //...
  mutex& getMutex();
};
Run Code Online (Sandbox Code Playgroud)

我可以using mutex = ParticularMutex在我的实现中使用直觉,但gcc告诉我:

error: conflicting declaration ‘using mutex = ’
error: ‘class mutex’ has a previous declaration as ‘class mutex’
Run Code Online (Sandbox Code Playgroud)

我没有定义任何两次,只是宣布两次,就像前面宣布的那样,所以

  1. 为什么这不起作用?
  2. 有没有修改的解决方法interface
  3. 应该怎么interface定义?用template <typename mutex>

c++ alias templates using forward-declaration

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

前向声明,unique_ptr和类内初始化器

我已经读过了std :: unique_ptr <T>需要知道T的完整定义吗?unique_ptr转发声明?,但我的问题更具体.

以下编译:

// Compile with $ g++ -std=c++11 -c <filename>
#include <memory>
class A; // fwd declaration

class AUser
{
  AUser();  // defined elsewhere
  ~AUser(); // defined elsewhere
  std::unique_ptr<A> m_a;
};
Run Code Online (Sandbox Code Playgroud)

以下不是:

// Compile with $ g++ -std=c++11 -c <filename>
#include <memory>
class A; // fwd declaration

class AUser
{
  AUser();  // defined elsewhere
  ~AUser(); // defined elsewhere
  std::unique_ptr<A> m_a{nullptr};
};
Run Code Online (Sandbox Code Playgroud)

错误

$ g++ -std=c++11 -c fwd_decl_u_ptr.cpp 
In file included from /usr/include/c++/4.7/memory:86:0,
                 from …
Run Code Online (Sandbox Code Playgroud)

c++ forward-declaration unique-ptr in-class-initialization

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

Stroustrup的C++编程语言出错?

Stroustrup的The C++ Programming Language(第4版)中的§6.3.5.1的最后一句是:

如果数组或结构是,则默认初始化数组或类的成员.

但是,此测试显示默认初始化对象的未初始化成员(我也试过g++4.7 -std=c++11)

#include <iostream>

struct Foo
{
    int i;

    Foo();
};

Foo::Foo() {}

int main()
{
    Foo f;
    std::cout << "f.i: " << f.i << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我必须遗漏一些东西,但有没有一个解释并不代表Stroustrup的肯定错误?


编辑:在答案之后,我理解默认初始化的概念应该包括在文本的其他部分中被称为初始化的概念(例如,在§17.3.1中).这对我来说听起来很不清楚.实际上,使用未初始化来表示除"未明确用户初始化"之外的任何内容(就像在那里一样)是一个矛盾:有些东西是默认初始化但尚未初始化.除非有人放弃X和un-X分类相反的自然语言证据,否则排他性......

此外,同一部分(第6.3.5.1节)中的较早句子也是如此

默认情况下,局部变量[...]不会被初始化,除非它们是具有默认构造函数的用户定义类型[...]

这里的矛盾再次明显.接受第一个和后一个语句都是真的意味着存在同时默认初始化默认情况下未初始化的变量(即局部变量).

恕我直言,这充其量是一种非常不清楚的自然语言用来描述某些东西.

c++ initialization default-constructor built-in-types

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

在C++ 11中返回本地值的最佳方法

在过去,如果我想要一个对象的字符串表示A,我会写一些带有签名的东西,void to_string(const A& a, string& out)以避免额外的副本.这仍然是C++ 11中的最佳实践,具有移动语义和所有?

我已经阅读了一些关于其他上下文的评论,这些评论建议依赖于RVO而不是写作string to_string(const A& a).但RVO并不能保证会发生!那么,作为to_string的程序员,我怎么能保证字符串不会被不必要地复制(独立于编译器)?

copy return-by-reference move-semantics c++11 return-by-value

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

对于自动变量,unused-variable警告不同

使用gcc(这里是4.7.2)我收到有关未使用的自动变量的警告,但没有关于其他变量的警告:

// cvars.h
#ifndef CVARS_H_
#define CVARS_H_

const auto const_auto = "const_auto";
const char const_char_array[] = "const_char_array";
const char * const_char_star = "const_char_star";
const char use_me = 'u';

#endif // CVARS_H_

//---
//comp_unit.cpp
#include "cvars.h"

void somef()
{
  //const_auto // commented out - unused
  use_me; // not using any of the others either
}

// compile with $ g++ -std=c++11 -Wunused-variable -c comp_unit.cpp
// gcc outputs warning: ‘cvars::const_auto’ defined but not used [-Wunused-variable]
// but does not complain about the …
Run Code Online (Sandbox Code Playgroud)

c++ gcc warnings auto unused-variables

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

在内部构造函数中,使用/ catch块将简单的内存分配到公共​​原始指针中?

我有一个带有原始指针的情况,我无法更改为智能指针,因为它是接口的一部分(我不想破坏使用它的任何代码):

struct Foo
{
  Foo();
  ~Foo();

  int * m_pStuff; // public!
};
Run Code Online (Sandbox Code Playgroud)

我不想在我的病人身上做太多事情.就像这样:

m_pStuff = new int[dynamically_obtained_size_which_is_greater_than_0];
m_pStuff[0] = 0;
Run Code Online (Sandbox Code Playgroud)

然后在析构函数中删除它.

现在,我想知道使用try/catch是否值得围绕它:

Foo::Foo()
  : m_pStuff(0)
{
  try
  {
    m_pStuff = new int[dynamically_obtained_size_which_is_greater_than_0];
    m_pStuff[0] = 0;
  } 
  catch(...)
  {
    delete m_pStuff;
    throw;
  }
}
Run Code Online (Sandbox Code Playgroud)

我能看到的观点:

  • 更复杂的代码
  • 并不是真的希望在那里发生任何异常(除非分配时空间不足)
  • 并不是真的希望代码能够改变

我能看到的要点:

  • 向潜在的未来编码者表明,他们应该小心处理任何抛出异常并将其放入已经存在的try块中
  • 如果发生任何异常,则会释放内存释放

我还是很犹豫:我是否应该尝试使用try/catch?为什么?我想就此提出你的意见.

此外,您是否看到在分配时由于内存不足而导致异常的可能性?在这种情况下,已经分配的内存将被自动回收,对吗?

谢谢!

c++ constructor pointers exception dynamic-memory-allocation

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