小编Vit*_*meo的帖子

更快的替代品.Distinct()

我正在制作一款性能至关重要的视频游戏.

我正在使用.Distinct()扩展方法从List获取唯一值.有更快的方法吗?(即使它意味着有更多的代码行)

.net c# linq

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

在C++中以便携式方式获取桌面分辨率

我正在制作一个C++游戏,我想让它自动获得用户的桌面分辨率.

到目前为止,我找到了仅限Windows的解决方案 - 是否有方法/库可以在Windows/Mac/Linux上找到解决方案?

c++ portability gcc screen-resolution

10
推荐指数
3
解决办法
5187
查看次数

std :: vector比std :: unordered_set更快?

在我的自定义物理引擎中,最大的瓶颈是从空间分区(2D网格)获取所有实体的方法,并返回仅包含指向身体的唯一指针的集合.

template<typename T, typename V> bool contains(const T& mContainer, const V& mValue)
{
    return std::find(std::begin(mContainer), 
                     std::end(mContainer), mValue) != std::end(mContainer);
}

const vector<Body*>& GridInfo::getBodiesToCheck()
{
    bodiesToCheck.clear();
    for(auto& query : queries)
        for(auto& body : *query)
            if(!contains(bodiesToCheck, body)) bodiesToCheck.push_back(body);
    return bodiesToCheck;
}
Run Code Online (Sandbox Code Playgroud)

使用分析器显示瓶颈在"包含"方法中.

显然,这std::unordered_set将是一个"理想"的解决方案.但是,它比当前解决方案慢很多.我也尝试过google::dense_hash_set,这std::unordered_set比当前解决方案更快,但仍然更慢.

const unordered_set<Body*>& GridInfo::getBodiesToCheck()
{
    bodiesToCheck.clear();
    for(auto& query : queries)
        for(auto& body : *query)
            /*if(!contains(bodiesToCheck, body))*/ bodiesToCheck.insert(body);
    return bodiesToCheck;
}
Run Code Online (Sandbox Code Playgroud)

为什么"正确"的容器比一个慢std::vector

有什么办法可以进一步加快这种方法的速度吗?

c++ performance stl vector unordered-set

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

g ++不会使用assert编译constexpr函数

template<typename T> constexpr inline 
T getClamped(const T& mValue, const T& mMin, const T& mMax) 
{ 
     assert(mMin < mMax); // remove this line to successfully compile
     return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue); 
}
Run Code Online (Sandbox Code Playgroud)

错误:constexpr函数主体 'constexpr T getClamped(const T&,const T&,const T&)[with T = long unsigned int]' not return-statement

g++ 4.8.1.clang++ 3.4不抱怨

谁在这?我可以g++在不使用宏的情况下编译代码吗?

c++ assert g++ constexpr c++11

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

使用索引避免迭代器失效,保持干净的接口

我创建了一个MemoryManager<T>类,它基本上是两个指针向量的包装器,用于管理堆分配对象的生命周期.

一个向量存储"活动"对象,另一个向量存储将在下一个添加的对象MemoryManager<T>::refresh.

选择此设计是为了避免在循环时使用迭代器失效MemoryManager<T>,因为直接向MemoryManager<T>::alive向量添加新对象会使现有迭代器无效(如果它的大小增大).

template<typename T> struct MemoryManager {
    std::vector<std::unique_ptr<T>> alive;
    std::vector<T*> toAdd;

    T& create() { 
        auto r(new T); 
        toAdd.push_back(r); 
        return *r; 
    }

    T& refresh() { 
         // Use erase-remove idiom on dead objects
         eraseRemoveIf(alive, [](const std::unique_ptr<T>& p){ return p->alive; });

         // Add all "toAdd" objects and clear the "toAdd" vector
         for(auto i : toAdd) alive.emplace_back(i); 
         toAdd.clear(); 
    }  

    void kill(T& mItem)  { mItem.alive = false; }

    IteratorType begin() { return alive.begin(); }
    IteratorType end() …
Run Code Online (Sandbox Code Playgroud)

c++ iterator vector invalidation c++11

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

如果`f`具有非void返回类型,则返回`f`的结果 - 如何重构此模式?

我有一个step(f)功能:

  1. 在调用之前执行一些代码f.

  2. 打电话f().

  3. 调用后执行一些代码f.

  4. 如果不返回返回f结果值.fvoid

step 由于上面提到的第四点,实现的一小段代码比我应该更困扰我:

template <typename TF>
auto step(TF&& f)
{   
    // Execute some actions before `f`. 
    do_something();

    using f_return_type = decltype(f());
    return static_if(std::is_same<f_return_type, void>{})
        .then([](auto&& xf) mutable
            {
                // Do not return anything if `xf` returns void.
                xf();

                // Execute some actions after `f`.
                do_something_after_f();
            })
        .else_([](auto&& xf) mutable
            {
                auto result = xf();

                // Execute some actions after `f`.
                do_something_after_f(); …
Run Code Online (Sandbox Code Playgroud)

c++ refactoring metaprogramming return-type c++14

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

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

缩小从`int`(常量表达式)到`unsigned int`的转换 - MSVC vs gcc vs clang

constexpr int i = 100;
struct F { F(unsigned int){} };
int main() { F{i}; }
Run Code Online (Sandbox Code Playgroud)

上面的代码:

  • 编译没有警告g++ 7-Wall -Wextra -Wpedantic.

  • 编译没有警告clang++ 4-Wall -Wextra -Wpedantic.

  • 无法编译MSVC 2017:

    从'const int'转换为'unsigned int'需要缩小转换

问:这是MSVC错了吗?

godbolt.org上的实例


int i = 100;
struct F { F(unsigned int){} };
int main() { F{i}; }
Run Code Online (Sandbox Code Playgroud)
  • 编译带有警告g++ 7-Wall -Wextra -Wpedantic:

    缩小'i'从'int'到'unsigned int'的转换

  • 编译失败clang++ 4-Wall -Wextra …

c++ type-conversion visual-c++ language-lawyer c++11

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

lambda捕获的"空基础优化" - 标准禁止?为什么?

我最近遇到了一种情况,我最终得到了大量嵌套的lambdas来构建异步计算链.

template <typename F>
struct node : F
{
    node(F&& f) : F{std::move(f)}
    {
    }

    template <typename FThen>
    auto then(FThen&& f_then)
    {
        return ::node{[p = std::move(*this), t = std::move(f_then)]()
        {   
        }};
    }
};

int main()
{
    auto f = node{[]{ }}.then([]{ }).then([]{ });
    return sizeof(f);
}   
Run Code Online (Sandbox Code Playgroud)

我在lambda中捕获的所有对象都是空的,但最终对象的大小大于1:gcc.godbolt.org上的示例.

如果我将lambda内部更改为node</* ... */>::then具有显式EBO的函数对象,则最终对象的大小将变为1.

template <typename P, typename T>
struct node_lambda : P, T
{
    node_lambda(P&& p, T&& t) : P{std::move(p)}, T{std::move(t)}
    {
    } …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++17

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

Using `extern template` with third-party header-only library

I am using the glm library, which is a header-only collection of math utilities intended for 3D graphics. By using -ftime-trace on Clang and ClangBuildAnalyzer, I've noticed that a lot of time is being spent instantiating glm types:

**** Templates that took longest to instantiate:
 16872 ms: glm::vec<4, signed char, glm::packed_highp> (78 times, avg 216 ms)
 15675 ms: glm::vec<4, unsigned char, glm::packed_highp> (78 times, avg 200 ms)
 15578 ms: glm::vec<4, float, glm::packed_highp> (78 times, avg 199 ms)

... …
Run Code Online (Sandbox Code Playgroud)

c++ templates extern explicit-instantiation c++11

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