我有一个纯粹的抽象基础和两个派生类:
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 …
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它,那么这种方法就会破坏.
我正在并行化一个已经存在的使用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)
并且感觉不对.
我有一个"列"容器类型:
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)
用法: …
我执行与代理迭代器/引用类型的容器类似,以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&& …
内存是否由唯一指针所拥有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.
我刚刚(再次)实现了一个递归模板,用于在编译时计算整数的阶乘(谁曾想过有一天我真的需要它!).尽管如此,我还是去找Boost寻找答案,而不是自己动手.但是,特殊数学中的阶乘函数特别禁止它使用整数类型,所以我只写了自己的.
仍然,我应该使用Boost中的另一个功能吗?我应该将我的整数转换为double并使用该boost::factorial函数吗?计算是在编译时执行的吗?
让我们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适合用作关联序列,但我还没有找到从中构造地图的方法.特别是,如果我迭代它,我只得到值.如果我可以迭代那些真正有用的键,因为那时我可以压缩值和键来构建一个映射,但我还没有找到一种方法来做到这一点.
我的大多数-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中.
这个程序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是一种整数类型,至少可以存储0和1,并且true是整数常量1.在我的机器上,_Bool有一个sizeof(_Bool) == 1,和CHAR_BITS == 8,这意味着_Bool有256个表示.
我在C标准中找不到关于陷阱表示的更多内容_Bool,我无法找到创建_Bool一个表示不同于0或1(在支持两个以上表示的实现上)是否正常,如果可以,这些陈述是表示真或假.
我可以在标准的发现是什么情况,当_Bool与整数相比,整数转换成0它是否有值表示0,并给1 …
c++ ×9
c++14 ×2
iterator ×2
algorithm ×1
arrays ×1
boolean ×1
boost ×1
boost-fusion ×1
c ×1
c++11 ×1
constexpr ×1
googletest ×1
linux ×1
math ×1
mpi ×1
namespaces ×1
performance ×1
proxy ×1
ubsan ×1