小编gnz*_*lbg的帖子

什么是以非多态方式调用虚函数的成本?

我有一个纯粹的抽象基础和两个派生类:

struct B { virtual void foo() = 0; };
struct D1 : B { void foo() override { cout << "D1::foo()" << endl; } };
struct D2 : B { void foo() override { cout << "D1::foo()" << endl; } };
Run Code Online (Sandbox Code Playgroud)

foo在A点呼叫的成本是否与对非虚拟成员功能的呼叫相同?或者它是否比D1和D2不是从B派生的更昂贵?

int main() {
 D1 d1; D2 d2; 
 std::vector<B*> v = { &d1, &d2 };

 d1.foo(); d2.foo(); // Point A (polymorphism not necessary)
 for(auto&& i : v) i->foo(); // Polymorphism necessary.

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

答案:Andy Prowl …

c++ performance virtual-functions

9
推荐指数
2
解决办法
537
查看次数

c ++库命名空间和C linux函数之间的名称冲突

Linux <ncurses.h>标头定义了该函数meta,C++元编程库meta将其所有代码放在全局名称空间中meta.

我怎样才能在同一个C++程序中使用它们(不一定是相同的TU,但那会很好)?有没有办法解决名称冲突?

我可以想到两个脆弱的解决方法,但它们很容易破解:

  • 解决方法A:

     namespace linux {
     #include <ncurses.h>
     }  // namespace linux
     using linux::max_align_t;  // ncurses assumes it is in the global namespace
     #include <meta/meta.hpp>
    
    Run Code Online (Sandbox Code Playgroud)

    编译但可能无法链接,因为ncurses符号在全局命名空间中是预期的.

  • 解决方法B:

    #include <ncurses.h>
    namespace cpp {
    #include <meta/meta.hpp>
    }  // namespace cpp
    
    Run Code Online (Sandbox Code Playgroud)

    非常脆弱,因为只有当meta库不假设它的任何符号都在全局命名空间中时它才会起作用.也就是说,如果库需要在内部消除歧义并使用::meta::symbol_name它,那么这种方法就会破坏.

c++ linux namespaces name-collision

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

使用gtest对MPI程序进行单元测试

我正在并行化一个已经存在的使用gTest和MPI的应用程序.在MPI程序中,首先要做的是通过调用来初始化环境

MPI_Init( int *argc, char ***argv )
Run Code Online (Sandbox Code Playgroud)

在MPI程序结束时,根进程也应该调用MPI_Finalize.如何使用Google Test为这样的应用程序编写单元测试?

特别是,如何 gTest修改它们之前从测试中访问argc和argv .

现在我正在做:

int argc = 0;
char** argv = NULL;
boost::mpi::environment env(argc,argv);

TEST(component_test, test_name) {
  // stuff using mpi
}
Run Code Online (Sandbox Code Playgroud)

并且感觉不对.

c++ mpi googletest

8
推荐指数
2
解决办法
1678
查看次数

(重新)将std :: algorithms与非标准容器一起使用

我有一个"列"容器类型:

struct MyColumnType { 
  // Data: Each row represents a member of an object.
  vector<double> a;   // All vectors are guaranteed to have always
  vector<string> b;   // the same length.
  vector<int> c;

  void copy(int from_pos, int to_pos); // The column type provides an interface
  void swap(int pos_a, int pos_b);     // for copying, swapping, ...

  void push_back();      // And for resizing the container.
  void pop_back();
  void insert(int pos);
  void remove(int pos);
  // The interface can be extended/modified if required
};
Run Code Online (Sandbox Code Playgroud)

用法: …

c++ algorithm proxy iterator

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

具有代理迭代器/引用和auto的容器

我执行与代理迭代器/引用类型的容器类似,以std::vector<bool>和冲突到了以下问题,我着手进行例举std::vector<bool>(这个问题不是std::vector<bool>!):

#include <vector>
#include <type_traits>
int main() {
  using namespace std;
  vector<bool> vec = {true, false, true, false};
  auto value = vec[2];  // expect: "vector<bool>::value_type"
  const auto& reference = vec[2]; // expect: "vector<bool>::const_reference"

  static_assert(is_same<decltype(value), vector<bool>::value_type>::value, 
                "fails: type is vector<bool>::reference!");
  static_assert(is_same<decltype(reference), 
                        vector<bool>::const_reference>::value,
                "fails: type is const vector<bool>::reference&!"); 

  /// Consequence:
  auto other_value = value; 
  other_value = false; 
  assert(vec[2] == true && "fails: assignment modified the vector");
Run Code Online (Sandbox Code Playgroud)
  • 有没有办法实现代理类型,以便静态断言传递?

  • 在实现这样的容器时,是否有关于如何处理此问题的指导原则?

也许通过使用转换运算符来auto/ auto&/ auto&& …

c++ iterator generic-programming c++11 c++14

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

是否需要std :: make_unique <T []>才能返回对齐的内存?

  • 内存是否由唯一指针所拥有array_ptr:

    auto array_ptr = std::make_unique<double[]>(size);
    
    Run Code Online (Sandbox Code Playgroud)

    对齐边界(即std要求正确对齐)?sizeof(double) alignof(double)

  • 数组的第一个元素是缓存行的第一个元素吗?

  • 否则:在C++ 14中实现这一目的的正确方法是什么?

动机(更新):我计划在阵列上使用SIMD指令,因为高速缓存行是每个架构上的基本内存单元,我知道我只是正确地分配内存,这样数组的第一个元素就在缓存行的开头.请注意,只要元素正确对齐(与高速缓存行之间元素的位置无关),SIMD指令就可以工作.但是,我不知道这是否会产生影响,但我可以猜测是的,确实如此.此外,我想在内核中的原始内存上使用这些SIMD指令.它是内核的优化细节,所以我不想分配例如__int128而不是int.

c++ arrays c++14

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

在编译时计算小整数的阶乘

我刚刚(再次)实现了一个递归模板,用于在编译时计算整数的阶乘(谁曾想过有一天我真的需要它!).尽管如此,我还是去找Boost寻找答案,而不是自己动手.但是,特殊数学中的阶乘函数特别禁止它使用整数类型,所以我只写了自己的.

仍然,我应该使用Boost中的另一个功能吗?我应该将我的整数转换为double并使用该boost::factorial函数吗?计算是在编译时执行的吗?

c++ math boost template-meta-programming constexpr

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

是否有可能从适应的结构生成融合图?

让我们A:

struct A {
  int a;
  std::string b;
  struct keys {
    struct a;
    struct b;
  };
};
Run Code Online (Sandbox Code Playgroud)

我想fusion::map从结构中生成一个它包含fusion::pairs:fusion::pair<A::keys::a, int>fusion::pair<A::keys::b, std::string>.就像是

A a;
fusion::make_map<A>(a)
Run Code Online (Sandbox Code Playgroud)

我试过了 BOOST_FUSION_ADAPT_ASSOC_STRUCT

BOOST_FUSION_ADAPT_ASSOC_STRUCT(
    A,
    (int,  a, A::keys::a)
    (std::string, b, A::keys::b)
Run Code Online (Sandbox Code Playgroud)

)

这使A适合用作关联序列,但我还没有找到从中构造地图的方法.特别是,如果我迭代它,我只得到值.如果我可以迭代那些真正有用的键,因为那时我可以压缩值和键来构建一个映射,但我还没有找到一种方法来做到这一点.

c++ boost-fusion

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

如何从UBsan中抑制一些无符号整数溢出错误?

我的大多数-fsanitize=unsigned-integer-overflow错误都是错误,但有时我会明确地按预期使用它,这会导致UBSan产生误报.

有没有办法为特定表达式转换UBSan无符号整数溢出检查?

编辑回应Shafik评论,这是一个例子:

unsigned a = 0;
unsigned b = a - 1; // error: unsigned integer overflow
Run Code Online (Sandbox Code Playgroud)

大多数时候这是一个错误,有时它不是.使用UBSan,每次发生时都可以找到,修复错误,但我还没有找到一种方法来消除误报.

编辑2:启用检查需要通过-fsanitize=integer(以启用所有整数检查)或fsanitize=unsigned-integer-overflow.从下面的评论看来,支票只能在clang中使用,而不是在GCC中.

c++ undefined-behavior ubsan

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

关于真实的表示可以假设什么?

这个程序0在我的机器中返回:

#include <stdbool.h>

union U {
    _Bool b;
    char c;
};

int main(void) {
    union U u;
    u.c = 3;
    _Bool b = u.b;
    if (b == true) {
        return 0;
    } else {
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

AFAICT _Bool是一种整数类型,至少可以存储01,并且true是整数常量1.在我的机器上,_Bool有一个sizeof(_Bool) == 1,和CHAR_BITS == 8,这意味着_Bool有256个表示.

我在C标准中找不到关于陷阱表示的更多内容_Bool,我无法找到创建_Bool一个表示不同于01(在支持两个以上表示的实现上)是否正常,如果可以,这些陈述是表示真或假.

我可以在标准的发现是什么情况,当_Bool与整数相比,整数转换成0它是否有值表示0,并给1 …

c boolean

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