小编Tim*_*imo的帖子

C ++将可变参数模板参数扩展为语句

我目前正在玩模板元编程。我正在尝试通过使用tmp来制作有限状态机。我知道网络上有几种实现方式,但是我想自己做一个练习。

我有一个称为的类Condition,它是两个状态之间转换的条件的基类。AnyCondition该类是一种实现:

template<class Input, Input comp, Input ... comps >
class AnyCondition: public Condition<Input>
{    
public:
    AnyCondition() {}

    bool operator()(const Input& input) const override
    {
        return input == comp || AnyCondition<Input, comps...>()(input);
    }

};
Run Code Online (Sandbox Code Playgroud)

此处的问题是,编译器将递归扩展此操作,由于该input参数,在运行时将导致大量递归调用。如果扩展后的代码如下所示,则应该更有效:

    bool operator()(const Input& input) const override
    {
        return input == comp1 || input == comp2 || input == comp3...
    }
Run Code Online (Sandbox Code Playgroud)

这有可能吗?

c++ templates template-meta-programming variadic-templates c++11

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

统计记录类型的成员

假设我有以下类型:

type BinaryOp =
    { Lhs: int
      Rhs: int
      Destination: int }
Run Code Online (Sandbox Code Playgroud)

是否有 F# 方法来计算该记录的成员,即countMembers<BinaryOp> = 3?我知道我可以使用,System.Reflection但我宁愿不使用。

f#

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

如何从 tbb::flow::graph 中删除/取消消息?

我构建了一个tbb::flow::graph由几个function_node对象组成的对象。在执行期间,我将多条消息传递到图中(从 ~10 到 ~100000)。有时其中一个节点会抛出异常。如果是这种情况,整个图的执行将被取消,这意味着所有消息都将被丢弃。但是,我的消息是相互独立的,我不希望它们的执行被停止。

我可以直接在节点内部捕获异常,但是当发生这种情况时,对消息的进一步处理将没有意义。

所以我的问题是:如何从图中取消或删除单个消息而不取消图中已经存在的其他消息的执行?

c++ tbb tbb-flow-graph

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

Intel TBB - 'InitializeCriticalSectionEx':未找到标识符编译器错误

我有一个依赖OpenCV和TBB的VS(C++)项目,所以我为每个库创建了属性表并将它们包含在项目中.一切正常,代码编译.

昨天,我已经开始使用vcpkg包管理器了.我通过vcpkg安装了OpenCV和TBB,一切似乎都有效.我创建了一个空项目,包括两者的标题,并测试新编译的库是否有效.在验证之后,我回到了我的主项目并删除了属性表,所以我可以使用vcpkg中的库.自上次成功编译以来,我没有以任何方式更改代码.

但是当我现在尝试编译代码时,我得到了两次这个错误(在main.cpp和子模块中)

tbb\critical_section.h(53):错误C3861:'InitializeCriticalSectionEx':未找到标识符

有谁知道这里发生了什么或为什么会发生这个错误?

更新

我自己发现了这个错误.我正在添加poco-libraries标签,因为它实际上是TBB和Poco之间的冲突.

c++ tbb poco-libraries c++17 vcpkg

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

为什么 __stdcall 调用约定在 x64 中被忽略?

我知道__cdecl和之间的区别__stdcall是什么,但我不太确定为什么__stdcall在 x64 构建中被编译器忽略。

以下代码中的函数

int __stdcall stdcallFunc(int a, int b, int c, int d, int e, int f, int g)
{
    return a + b + c + d + e + f + g;
}

int __cdecl cdeclFunc(int a, int b, int c, int d, int e, int f, int g)
{
    return a + b + c + d + e + f + g;
}

int main()
{
    stdcallFunc(1, 2, 3, …
Run Code Online (Sandbox Code Playgroud)

c++ x86-64 calling-convention visual-c++

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

我可以在输入迭代器上定义开始和结束吗?

假设我有一个MyInputIter满足该概念的输入迭代器类型(我用它来遍历树状结构)std::input_iterator

我有什么理由不应该在迭代器本身上定义begin()and吗?end()

struct MyInputIter
{
    // iterator stuff omitted

    auto begin() const { return *this; }
    auto end() const { return MySentinel{}; }
};
Run Code Online (Sandbox Code Playgroud)

原因是我不必创建另一种类型来包装beginend因此我可以在 for 循环中使用它:

MyInputIter iterate(TreeNode root, FilterPattern pattern)
{
    return MyInputIter{ root, pattern };
}

void foo()
{
    for (auto item : iterate(someRandomTreeNode, "*/*.bla"))
        process(item);
}
Run Code Online (Sandbox Code Playgroud)

同时还可以将其用作迭代器:

std::vector<TreeNode> vec(iterate(someRandomTreeNode, "*"), MySentinel{});
Run Code Online (Sandbox Code Playgroud)

c++ c++20

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

接受两个接口之一的方法

问题

我有两个接口IImporterIExporter一个处理这些接口实例的类:

class IoManager
{
    public ReadOnlyCollection<IImporter> Importers { get; } 
    public ReadOnlyCollection<IExporter> Exporters { get; }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

在这个类中,我想实现一个Add(...)可以添加导入器或导出器的方法.

我知道我可以为两个接口创建一个重载

public void Add(IExporter exporter);
public void Add(IImporter importer);
Run Code Online (Sandbox Code Playgroud)

问题是如果我想添加一个实现两个接口的对象,比如CsvIo : IImporter, IExporter通过Add(...)函数,我得到一个不明确的调用编译错误,因为CsvIo两个重载都接受了.

我不想做什么

  • 我不想重载重命名为不同的名字,因为大多数类型的实现这两个接口和我想要实现的类型一致的行为IExporter,IImporter或两者兼而有之.
  • 我不想创建由两个接口实现的"父"接口,因为这似乎是一个hacky解决方案
  • 我不想在Add(...)调用中强制转换类型Add((IImporter) CsvIoInstance),因为这表明只使用了这种类型的导入器.但是两个重载都检查对象是否实现了两个接口并相应地将它添加到两个列表中.

这个问题

有没有办法以连贯的方式接受不同的类型(这样每个类型的调用看起来都一样)?

编辑

澄清我的实现:这是插件系统的一部分.我想添加多种方式来存储我的数据(以便其他应用程序可以使用它).该IExporter接口用于在IImporter接口加载数据时存储数据.该IoManager管理所有注册的插件.当然,一个类可以(并且可能是常见的)实现某种文件格式的导出和导入.这就是为什么我希望Add(...)函数在所有情况下都相似.

但是,再次考虑它(如评论中已经说明的那样)插件只在运行时才知道,这使得模糊性成为我认为的过时问题.所以这只适用于内置类型.

.net c#

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


检查 ITypeSymbol 是否为委托类型

如何检查ITypeSymbol实例是否引用委托类型(如ActionFunc<T>)。

我想我可以检查基本类型是否为System.Delegate. 这是正确的方法还是有更好的解决方案?

c# roslyn roslyn-code-analysis

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

可能(真实)属性的重点是什么

我只是在cppreference上阅读C++中的属性.他们在那里提到了可能的(真实)属性,现在我想知道它有什么好处.不幸的是,我无法在网上找到更多信息.

这是处理器在执行期间使用的某种分支预测吗?

c++ attributes

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

unsigned long long(10) 无法在 clang 和 gcc 上编译

以下代码被 clang 和 gcc 拒绝,但被 msvc 接受:

#include <iostream>

int main() 
{
    std::cout << unsigned long long(10);
}
Run Code Online (Sandbox Code Playgroud)

错误是

错误:“无符号”之前的预期主表达式

神箭

这应该编译,对吧?

c++

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

如果一个唯一的指针是一个捕获的值,为什么它不能在lambda内移动?

以下代码无法编译:

struct S{};

void foo(std::unique_ptr<S> ptr)
{
    auto l = [p = std::move(ptr)]()
    {
        auto p2 = std::move(p);
    };
    l();
}
Run Code Online (Sandbox Code Playgroud)

原因是std::move(p)返回一个左值引用,因此编译器尝试调用被删除的复制构造函数。为什么move在这里返回左值引用?

是一个完整的示例。

c++ c++17

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

为什么来自不同类型层次结构的指针之间的动态转换定义得很好?

这是一个后续问题:当目标指针不是基类的类型时,为什么允许 dynamic_cast 为多态类产生空指针?.

C++17 标准dynamic_cast§8.2.7 [expr.dynamic.cast]下指定。

§8.2.7 (1) 状态

表达式dynamic_cast<T>(v)的结果是将表达式 v 转换为类型 T 的结果。 T 应是指向完整类类型的指针或引用,或“指向 cv void 的指针”。[...]

(2) 指定值类别,(3) 同一类型内的 cv 转换和 (4)nullptr大小写。[expr.dynamic.cast] 的每个其他段落都与同一类型层次结构中的多态类型相关联。

dynamic_cast除了在同一类型层次结构中的类型之间进行转换之外,我不知道任何用例。鉴于以下类型:

struct A
{
    virtual ~A() = default;
};

struct B : A
{
    virtual ~B() = default;
};
Run Code Online (Sandbox Code Playgroud)

A*可以强制转换为B*,这可能是最常见的用例dynamic_cast

A* ptr = new B;
dynamic_cast<B*>(ptr);
Run Code Online (Sandbox Code Playgroud)

我期望这将编译,因为BA在同一类型层次(B源自A)。在定义良好的程序中,类型指针A* …

c++ language-lawyer

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