小编Fla*_*ire的帖子

在 C++ 中使用模板回调函数

我想要一个基于给定回调函数检查某些条件的函数。

考虑这个代码:

class Foo{
template <class ParamType>
struct IsGood
{
    typedef bool (*Check)(typename const ParamType*, int other);
};
template< typename ParamType >
void DoSmth(IsGood<ParamType>::Check isGood, const ParamType* param){
   //...
   if(isGood(param, some_int_calculated_here)) doSmthElse();
}
Run Code Online (Sandbox Code Playgroud)

我想要的是这样称呼它:

bool checkEqualInt(int* i, int j){return *i==j;}
bool checkEqualFloat(float* i, float j){return *i==j;}

DoSmth(checkEqualInt, &i);
DoSmth(checkEqualFloat, &i_float);
Run Code Online (Sandbox Code Playgroud)

(所有构造的例子来说明问题)

编译器不会得到它,并抛出错误 C2664“不可能在 bool(ParamType,int) 中从 bool(int*,int) 转换参数 1”

我有一个不使用的解决方案

template< typename ParamType, Check >
void DoSmth(Check isGood, const ParamType param)
Run Code Online (Sandbox Code Playgroud)

哪个省略了检查功能的必要声明?

最好的解决方案是在函数本身中获取 IsGood() 标头。

c++ templates callback c2664

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

迭代方向枚举

我有一个带有6个方向条目(N,NE,SE,S,SW,NW)的方向枚举,它们基本上是图形中节点的边缘.我经常需要迭代所有邻居,这些邻居当前通过仅使用int从0-> 5迭代完成.

有时候还需要从例如2-> 1的环绕中进行迭代,其中当前通过从2-> 2 + 5迭代并在使用时将其调整为6来完成.

有什么我可以做的更安全/更容易使用而不会失去性能?具有固定整数范围的for循环可以展开,内联等.基于矢量的方法不能(在枚举内使用静态const向量)

我已经在以下方案中使用枚举:

struct Direction{
    enum Type{
        N, NE, ...
    }
    unsigned COUNT = ...;
    Type t_;
    operator Type(){return t_;}
    Direction(Type t):t_(t){assert(N<=t<COUNT);}
    explicit Direction(unsigned t):t_(t%COUNT){}
    static Direction fromUInt(unsigned t){return Direction(Type(t));}
}
Run Code Online (Sandbox Code Playgroud)

所以我想要的是拥有允许在整个集合上有效迭代的迭代器,并允许这个任意起始点,在这种情况下迭代器会包装.

怎么会写这个?我无法想象任何事情,因为我会有例如start = end的整个循环,这将是无效的.或者我只有start = givenStartType,end = start + COUNT并在每个迭代器deref上做一个模数?

不幸的是,没有C++ 11允许

c++ enums iterator loops

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

如何使用cmake创建MacOS应用程序捆绑包

这可以被视为带有Qt应用程序的BundleUtiliies的CMake MacOS X捆绑软件的后续产品

我想在CI上创建一个MACOS捆绑包,用户可以将其用于开源项目。

是)我有的:

  • 主要可执行文件
  • 更新程序可执行文件
  • 图标文件
  • 辅助脚本先调用updater然后再调用main
  • 文件夹中的数据文件(翻译等,有些在构建时生成)
  • 插件共享库

到目前为止,我所做的是:

  • 添加MACOSX_BUNDLE到可执行文件
  • 将图标添加到其来源和RESOURCE属性
  • 设置MACOSX_BUNDLE_*属性
  • 以跨平台的方式安装所有内容(常规install(TARGETS调用和install(FILES资源安装)

但是,现在我仍然停留在如何将这些东西打包而无需进行大量手动工作的问题上。

从链接的问题中我得到了这样的东西:

set(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app")
set(LIBS )
set(DIRS "${CMAKE_BINARY_DIR}")
# Path used for searching by FIND_XXX(), with appropriate suffixes added
if(CMAKE_PREFIX_PATH)
        foreach(dir ${CMAKE_PREFIX_PATH})
                list(APPEND DIRS "${dir}/bin" "${dir}/lib")
        endforeach()
endif()
install(CODE "include(BundleUtilities)
  fixup_bundle(\"${APPS}\" \"${LIBS}\" \"${DIRS}\")")
Run Code Online (Sandbox Code Playgroud)

但:

  • 为什么需要*.app手动通过路径?CMake已经知道了,不是吗?
  • LIBS应该包含我的插件,不是吗?但是呢 路径?目标名称?
  • DIRS对我来说也是一个谜。即使在CMake 3.12中也没有文档(尽管我仍在使用2.8.12 :()
  • 如何添加生成的常规数据文件?可能与图标相同或相似?但是生成的那些呢?

帮助,示例指针,完整的CMakeLists等等,非常欢迎。

注意:我是从CI上的linux交叉编译的,而不是使用Qt的,所以例如eg macdeployqt左右毫无疑问。

macos bundle cmake

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

访问成员变量中的引用会丢弃constness

我在我的代码中围绕一个对象创建了一个包装器,它应该修改对该对象的访问.我选择在这里使用一个对象进行测试,而不是一个具有相同功能的仿函数.基本上:包装器接收对对象的引用并转发对对象的所有索引访问(在一些可能的操作之后)
现在出现问题:访问器丢弃包装对象的常量.
最小的例子

struct Foo
{
    std::array<int, 2> data;
    const int& operator()(int idx) const{
        return data[idx];
    }
    int& operator()(int idx){
        return data[idx];
    }
};

struct Bar
{
    Foo& ref;
    Bar(Foo& r):ref(r){}
    int& operator()(int idx) const{
        return ref(idx);
    }
};

template< typename T >
void test(const T& data){
    data(1) = 4;
    std::cout << data(1);
}

void main(){
    Foo f;
    test(f);
    // Above call does not compile (as expected)
    // (assignment of read-only location)
    Bar b(f);
    test(b); // This does compile and …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors const reference c++11

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

从 CMake 运行 pytest 测试,其中测试和源位于不同的文件夹中

我有一个使用 C++ 和 python 源代码的基于 CMake 的项目。测试是通过add_test为文件夹结构中的所有 C++ 测试添加的,例如:

src
  mynamespace/foo.cpp
  mypyspace/mypkg/__init__.py
  mypyspace/mypkg/bar.py
test
  mynamespace/testFoo.cpp
  mypyspace/testBar.py
Run Code Online (Sandbox Code Playgroud)

testBar.py我有一个import mypkg并且想要运行它add_test(... COMMAND pytest WORKING_DIRECTORY .../test)

当然它没有找到我的包,但我也不想安装它(它需要在构建过程中生成一些东西,并且作为其他源的一部分积极开发)。

执行这些测试的正确/首选方法是什么?

笔记:

  • 我不想将源移出src或测试移出test
  • set_tests_properties 可以设置环境变量。

我认为设置PYTHONPATH=.../src/mypyspace应该有效,但这也会忽略对用户的更改PYTHONPATH

python cmake pytest python-3.x

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

创建一个随机数的向量

我如何创建一个充满随机数的向量?

通常的代码是:

std::mt19937 rng {std::random_device{}()};
std::uniform_int_distribution<int> dist {1, 52};

std::vector<int> vec(10);
std::generate(begin(vec), end(vec), [&]{return dist(rng);} );
Run Code Online (Sandbox Code Playgroud)

然而,这意味着每个值都被触摸两次:一旦设置为零,然后设置为随机值(即使在O3处)

那么如何尽可能高效地做到这一点呢?

c++ random c++11

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

如何在DLL导出的接口中处理析构函数

我正在尝试从DLL导出类。我阅读了此文章:http : //www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

“成熟”的方法建议使用抽象类,因此我有:

// Header
class IFoo{
public:
    virtual int getBar() = 0;
}

class Foo: public IFoo {...}

DLLEXPORT IFoo* Create();
DLLEXPRT void Free(IFoo* inst);

//DLL cpp
IFoo* Create(){ return new Foo; }
void Free(IFoo* inst){ delete inst; }
Run Code Online (Sandbox Code Playgroud)

让我感到困惑的是:如果我没有虚拟析构函数,则delete inst不会调用Foos析构函数,并且可能会泄漏内存。我应该如何处理?本文没有给出答案。

使用virtual ~IFoo(){}是不可能的,因为这会向IFoo中添加一个实现,该实现会导致问题(在有关内联虚拟函数的文章中对问题的回答中作了解释),并virtual ~IFoo() = 0;因未定义符号上的链接器错误而失败~IFoo

安全的方法是什么?释放/释放功能应如何实现?

c++ dll destructor pure-virtual dllexport

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

剩余时间测量的 std::chrono::duration 溢出

我想知道,还有多少时间让事件发生。我为此使用 boost::chrono 或 std::chrono 。

基本上算法是这样的:

using std::chrono; // Just for this example
auto start = steady_clock::now();
seconds myTotalTime(10);
while(true){
  auto remaining = start + myTotalTime - steady_clock::now();
  seconds remainingSecs = duration_cast<seconds>(remaining);
  if(remainingSecs.count() <= 0) return true;
  else print("Remaining time = " + remainingSecs.count()); // Pseudo-Code!
}
Run Code Online (Sandbox Code Playgroud)

现在(理论上)可能会发生以下情况:start接近时钟周期的末尾(IMO 不知道这0意味着什么,所以它可能是任意的)。
然后start + myTotalTime可能溢出,减法可能下溢。

即使是简单的事情,如steady_clock::now() - start可能下溢。

对于无符号类型,这不是问题。如果它们是无符号的,那么标准保证steady_clock::now() - start在溢出now()和下溢减法的情况下我仍然得到正确数量的“单位” :10 - 250 = 10 + 256 - 255 …

c++ integer-overflow c++11 c++-chrono

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

初始化变量以减少omp

OpenMP标准指定了缩减变量的初始值.所以我必须初始化变量,在下列情况下我该怎么做:

int sum;
//...
for(int it=0;i<maxIt;i++){
#pragma omp parallel
{
  #pragma omp for nowait
  for(int i=0;i<ct;i++)
    arrayX[i]=arrayY[i];

  sum = 0;
  #pragma omp for reduction(+:sum)
  for(int i=0;i<ct;i++)
    sum+=arrayZ[i];
}
//Use sum
}
Run Code Online (Sandbox Code Playgroud)

请注意,我只使用1个并行区域来最小化开销并允许第一个循环中的nowait.使用这个原样将导致数据竞争(IMO),因为在其他线程启动第二个循环之后来自第一个循环的线程将重置总和.
当然,我可以在外部循环的顶部执行此操作,但在一般情况下,对于大型代码库,您可能会忘记您需要或已将其设置在那里会产生意外结果.
"omp single"有帮助吗?我怀疑当线程A执行单个时,另一个线程可能已进入减少循环."omp障碍"是可能的,但我想避免它,因为它击败了"nowait".

又一个例子:

#pragma omp parallel
{
  sum = 0;
  #pragma omp for reduction(+:sum)
  for(int i=0;i<ct;i++)
    sum+=arrayZ[i];
  //Use sum
  sum = 0;
  #pragma omp for reduction(+:sum)
  for(int i=0;i<ct;i++)
    sum+=arrayZ[i];
  //Use sum
}
Run Code Online (Sandbox Code Playgroud)

我将如何(重新)初始化?

c++ for-loop openmp reduction

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

C#中的IIR低通滤波器在x86模式下中断

我正在尝试在C#中使用IIR LP滤波器.这是一个五阶巴特沃斯滤波器.代码在64位模式下工作,但在32位模式下中断.调试显示,参数略有不同,输出升至无穷大/ NAN.我正在使用双打进行计算和存储.正确的参数a [i],b [i]是:

-5 -4,9792522401964
10 9,91722403267282
-10 -9,87615728025693
5 4,91765142871949
-1 -0,979465940928259

32位计算得到这些:

-5 -4,97925281524658
10 9,91722583770752
-10 -9,87615966796875
5 4,91765308380127
-1 -0,979466378688812

过滤代码:

    public void FilterBuffer(float[] srcBuf, long srcPos, float[] dstBuf, long dstPos, long nLen)
    {
        const double kDenormal = 0.000000000000001;
        double denormal = m_invertDenormal ? -kDenormal : kDenormal;
        m_invertDenormal = !m_invertDenormal;

        for (int sampleIdx = 0; sampleIdx < nLen; sampleIdx++)
        {
            double sum = 0.0f;

            m_inHistory[m_histIdx] = srcBuf[srcPos + sampleIdx] + denormal;

            for (int idx …
Run Code Online (Sandbox Code Playgroud)

c# signal-processing lowpass-filter

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