小编Vit*_*meo的帖子

绑定元函数:接受两种类型和模板模板参数(接受任何东西)

我正在尝试编写一个Bind元编程模板辅助元函数,它将模板参数绑定到某个东西上.

我有一个简单模板元函数的工作实现:

template<typename T0, typename T1>
struct MakePair
{
    using type = std::pair<T0, T1>;
};

template<template<typename...> class TF, typename... Ts>
struct Bind
{
    template<typename... TArgs>
    using type = TF<Ts..., TArgs...>;
};

using PairWithInt = typename Bind<MakePair, int>::type;
static_assert(std::is_same<PairWithInt<float>, MakePair<int, float>>{}, "");
Run Code Online (Sandbox Code Playgroud)

但是,如果MakePair模板参数是模板模板呢?还是简单的数值?

template<template<typename> class T0, template<typename> class T1>
struct MakePair0
{
    using type = /*...*/;
};

template<template<typename...> class TF, template<typename> class... Ts>
struct Bind0 { /*...*/ }

// ...

template<int T0, int T1>
struct MakePair1
{ …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming template-templates c++14

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

函数的随机整数总是返回相同的数字 - 为什么?

我目前正在学习C++并且对random_device有疑问.

我正试图模拟monty hall问题.为此,我需要随机整数来随机选择门.因此,我尝试创建一个为此目的返回随机整数的函数.

int guessGetRandomIndex() {
    std::random_device rd; // obtain a random number from hardware
    std::mt19937 eng(rd()); // seed the generator
    std::uniform_int_distribution<> distr(0, 2);
    return distr(eng);
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试在main()中获取随机整数时,我会保持相同的数字.

    vector<int> v = {0, 1, 2, 3, 4, 5};
for (auto & j : v){
    int random = guessGetRandomIndex();
    std::cout << random << ' ';
}    
 Output: 1 1 1 1 1 etc.
Run Code Online (Sandbox Code Playgroud)

然而,当我将随机设备放在主循环中并执行相同操作时,我设法得到随机整数.

    std::random_device rd; // obtain a random number from hardware
std::mt19937 eng(rd()); // seed the generator
std::uniform_int_distribution<> distr(0, 2); // …
Run Code Online (Sandbox Code Playgroud)

c++ random stl

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

在具有引用成员的对象上使用放置`new`的结果

"使用放置新更新基准部件?" 问题显示了这个例子(简化):

struct Foo { int& v_; };

int a, b;
Foo f{a};

new (&f) Foo{b};

assert(&f.v_ == &a); // UB
Run Code Online (Sandbox Code Playgroud)

f通过其原始名称访问肯定是UB,正如TC在链接问题中解释的那样.我知道std::launder可以用来解决这个问题:

assert(&std::launder(&f)->v_ == &a); // OK, will fire the assert
Run Code Online (Sandbox Code Playgroud)

但是使用放置返回的指针怎么样new?即

auto p = new (&f) Foo{b};    
assert(&(p->v_) == &a); // UB? OK?
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们不是通过原始名称引用对象,而是通过new返回的任何位置引用对象.

这是未定义的行为还是标准所允许的?

c++ const placement-new language-lawyer c++17

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

是否有一种无分支的方法可以将数字移动到另一个数字而不超过它?

我想实现一个符合以下接口和契约的函数:

void move_towards(float& value, float target, float step) 
    // Moves `value` towards `target` by `step`. 
    // `value` will never go beyond `target`, but can match it.
    // If `step == 0.0f`, `value` is unchanged.
    // If `step > 0.0f`, `std::abs(target - value)` decreases.
    // If `step < 0.0f`, the behavior is undefined.
Run Code Online (Sandbox Code Playgroud)

其想法是使用此函数逐渐将现有浮点值移向另一个浮点值,而不会超过目标。例如,这对于在值之间执行线性转换作为游戏循环执行的一部分非常有用。

这是一个测试用例示例:

float value = 5.0f;
move_towards(value,  10.f,  1.f); assert(value ==  6.0f);
move_towards(value,  10.f,  1.f); assert(value ==  7.0f);
move_towards(value, -5.f,   5.f); assert(value ==  2.0f);
move_towards(value, -5.f,   5.f); assert(value …
Run Code Online (Sandbox Code Playgroud)

c++ math floating-point optimization branchless

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

clang vs gcc - 从模板参数派生的结构的 CTAD

考虑以下代码:

template <typename B>
struct D : B { };

D d{[]{ }};
Run Code Online (Sandbox Code Playgroud)
  • gcc 12.x 接受它并推断出结果与预期d一致D</* type of lambda */>

  • clang 14.x 拒绝它并出现以下错误:

<source>:4:3: error: no viable constructor 
              or deduction guide for deduction of template arguments of 'D'
D d{[]{ }};
  ^

<source>:2:8: note: candidate template ignored: 
              could not match 'D<B>' against '(lambda at <source>:4:5)'
struct D : B { };
       ^

<source>:2:8: note: candidate function template not viable: 
              requires 0 arguments, but 1 was provided …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++20 ctad deduction-guide

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

浮点精度和物理计算

物理世界中的引力Vector2是(0; 0.1).

已知数字0.1是有问题的,因为"它不能准确表示,但是大约是1.10011001100110011001101×2-4".

拥有重力的这个值给了我碰撞的问题,并产生了非常讨厌的错误.将值更改为0.11可解决这些问题.

有没有更优雅的解决方案,根本不需要改变价值?


这个bug的视频

http://www.youtube.com/watch?v=bRynch1EtnE


源代码

http://pastebin.com/jNkqa3sg

第一种方法(AABBIsOverlapping)检查两个AABB实体之间的交集.每帧为每个主体调用第二个方法(Update).

我将尝试解释Update方法的工作原理:

  1. 将重力加速度矢量添加到速度矢量
  2. 创建临时矢量(下一个)并将其设置为速度
  3. 在当前正文周围的单元格中获取空间哈希中的实体
  4. 如果存在水平重叠,请解决它,将next.X和velocity.X设置为0并移动播放器
  5. 如果存在垂直重叠,请解决它,将next.Y和velocity.Y设置为0(或设置为0.1以防止从天花板不断跳跃)并移动播放器
  6. 循环之后,如果没有重叠,则移动播放器

c# floating-point physics

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

如何在Linux x86 NASM中打印字符?

我正在尝试使用NASM打印单个字符或数字,目标是x86 GNU/Linux体系结构.

这是我正在使用的代码:

section .text
    global _start

_start:

    ; Linux printing preparation
    mov eax,4            
    mov ebx,1       

    ; Print 'A' character 
    mov ecx,'A'     ; ecx should contain the value to print
    mov edx,1       ; edx should contain how many characters to print
    int 80h

    ; System exit
    mov eax,1            
    mov ebx,0            
    int 80h
Run Code Online (Sandbox Code Playgroud)

但是,运行此代码不会打印任何内容.我究竟做错了什么?

linux x86 assembly nasm system-calls

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

从成员中查找struct的基址的标准方法

struct Data {
    int a;
    std::string b;
    float c;
};

std::string* allocateDataAndGetString() {
    Data* dataPtr(someAllocator.allocate<Data>());
    return &dataPtr.b;
}

Data* getBaseDataPtrFromString(std::string* mStringMember) {
    // ???
}

int main() {
    std::string* stringPtr(allocateDataAndGetString());
    Data* dataPtr(getBaseDataPtrFromString
}
Run Code Online (Sandbox Code Playgroud)

Data在堆上分配了一个实例,并指向了它的std::string b;成员.如何Data以标准方式获取字符串所属实例的基址,并考虑偏移和填充?

我试过减sizeof(int)std::offsetof(Data, std::string)std::string*指针,但我无法得到它的工作.

c++ struct offsetof memory-address c++11

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

从可变参数类型列表中获取最大类型

我试图从可变参数模板类型列表中获取最大的类型.我得到了意想不到的结果:

// Bigger between two types
template<typename T1, typename T2> 
using Bigger = std::conditional_t<sizeof(T1) >= sizeof(T2), T1, T2>;

// Recursion helper
template<typename...> 
struct BiggestHelper;

// 2 or more types
template<typename T1, typename T2, typename... TArgs> 
struct BiggestHelper<T1, T2, TArgs...>
{
    using Type = Bigger<T1, BiggestHelper<T2, TArgs...>>;
};

// Exactly 2 types
template<typename T1, typename T2> 
struct BiggestHelper<T1, T2>
{
    using Type = Bigger<T1, T2>;
};

// Exactly one type
template<typename T> 
struct BiggestHelper<T>
{
    using Type = T;
};

template<typename... …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-templates c++11 c++14

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

如何在unordered_map中存储2个以上的变量?

如何在一个std::unordered_map?中存储2个以上的变量?

我想要这样的东西:

std::unordered_map<string, int, int, int> mapss = {{"a",1,1,1},{"b",1,2,3}};
Run Code Online (Sandbox Code Playgroud)

c++ unordered-map

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