小编Jos*_*vin的帖子

constexpr对象有没有办法引用/指向其他非静态constexpr对象?

假设我想在编译时使用某种算法构建图形,然后计算图形中结束的节点数.这似乎是constexpr的理想情况,而不是模板元编程,因为目标是计算产生一个值,而不是真正的类型.我有一些有用的代码,但功能是如此新,我担心编译器是宽松的,我可以解释部分标准说我不能这样做.

#include <iostream>

struct A { int x; constexpr A(int i) noexcept : x{i} {} };
struct B { A& a; constexpr B(A& a) noexcept : a{a} {} };

constexpr int foo() { 
    A a{55};
    B b{a};
    return b.a.x;
}

template<int N>
void output()
{
    std::cout << N << std::endl;
}

int main() {
    // to be absolutely sure compile time eval'd,
    // pass as template arg
    constexpr auto b = foo();
    output<b>();
}
Run Code Online (Sandbox Code Playgroud)

这两个ab实例都是在编译时创建的,它们具有相同的生命周期,所以这应该是"安全的".但这a …

c++ standards metaprogramming constexpr c++14

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

现代CPU缓存是否经过优化以应对不断的跨越?穿越线程?

假设我有一个大数组,并且有多个线程从数组中读取.每个线程通过跳过一个恒定量迭代数组,但从不同的偏移量开始.因此,线程1可以从元素0开始,然后读取元素32,64,96等.但是线程2从元素1开始,并且读取元素33,65,97等(记住'元素'可以构成不止一个字节或单词)我知道通常空间局部性对于获得最佳缓存性能是可取的,但我还读到现代CPU具有寻找访问模式的硬件预取器,并且对我的一个步幅似乎是一个明显的模式.

  • 这个缓存在现代包装盒上是否友好,或者不是吗?
  • 如果我将步幅增加到大于缓存行的大小,该怎么办?
  • 答案是否受到多线程的影响(所以尽管访问相同的内存,它们可能运行在具有不同缓存的不同内核上)?

architecture performance multithreading caching prefetch

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

decltype导致is_same <T,T>失败(相同类型)

在下面的代码片段中,我可以使is_same声称两种类型是不同的,即使它们具有相同的受损名称,并且这在GCC和clang中都有效.这只发生在我使用decltype时,如果我使用注释掉的行,那么编译器认为两种类型都与预期相同.这是某种预期的标准符合行为,还是这个错误?

#include <iostream>
#include <type_traits>
#include <typeinfo>

template <typename T, typename X>
void show(T, X)
{
    auto same = std::is_same<typename T::bar, X>::value;
    std::cout << "They are " << (same ? "the same" : "NOT the same") << std::endl;

    // the same string is always printed both times
    std::cout << typeid(typename T::bar).name() << std::endl;
    std::cout << typeid(X).name() << std::endl;
}

template <typename T>
struct Foo
{
    static constexpr struct E {} nested {};
    using bar = decltype(nested); // They are NOT …
Run Code Online (Sandbox Code Playgroud)

c++ templates rtti decltype type-traits

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

x86-64上最快的方法来检查指针范围是否跨越N字节对齐的地址?

给定一个指向T的指针,我想确定T是否跨越N字节对齐的地址.在实践中我真的只关心0-5字节大小的对象是否跨越8或16字节字节边界,但我写了这个通用版本:

template<class T, unsigned long N>
bool straddlesBoundary(T* obj)
{
    unsigned long before = (unsigned long)obj & ~(N-1);
    unsigned long after  = ((unsigned long)obj + sizeof(T) - 1) & ~(N-1);
    return before != after;
}
Run Code Online (Sandbox Code Playgroud)

基本上,将地址向下舍入到最接近的N字节对齐地址,然后将指针增量乘以T的大小减1(因为T在下一个边界上的右边不算作跨骑)并将其向下舍入到最近N字节对齐的地址,如果匹配,则表示它不会跨越.

有更快的方法吗?我刚刚做了这个,我不知道是否有标准检查.

编辑:注意,我假设T小于N.

c++ bit-manipulation x86-64 simd alignment

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