我目前正在玩模板元编程。我正在尝试通过使用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
假设我有以下类型:
type BinaryOp =
{ Lhs: int
Rhs: int
Destination: int }
Run Code Online (Sandbox Code Playgroud)
是否有 F# 方法来计算该记录的成员,即countMembers<BinaryOp> = 3?我知道我可以使用,System.Reflection但我宁愿不使用。
我构建了一个tbb::flow::graph由几个function_node对象组成的对象。在执行期间,我将多条消息传递到图中(从 ~10 到 ~100000)。有时其中一个节点会抛出异常。如果是这种情况,整个图的执行将被取消,这意味着所有消息都将被丢弃。但是,我的消息是相互独立的,我不希望它们的执行被停止。
我可以直接在节点内部捕获异常,但是当发生这种情况时,对消息的进一步处理将没有意义。
所以我的问题是:如何从图中取消或删除单个消息而不取消图中已经存在的其他消息的执行?
我有一个依赖OpenCV和TBB的VS(C++)项目,所以我为每个库创建了属性表并将它们包含在项目中.一切正常,代码编译.
昨天,我已经开始使用vcpkg包管理器了.我通过vcpkg安装了OpenCV和TBB,一切似乎都有效.我创建了一个空项目,包括两者的标题,并测试新编译的库是否有效.在验证之后,我回到了我的主项目并删除了属性表,所以我可以使用vcpkg中的库.自上次成功编译以来,我没有以任何方式更改代码.
但是当我现在尝试编译代码时,我得到了两次这个错误(在main.cpp和子模块中)
tbb\critical_section.h(53):错误C3861:'InitializeCriticalSectionEx':未找到标识符
有谁知道这里发生了什么或为什么会发生这个错误?
我自己发现了这个错误.我正在添加poco-libraries标签,因为它实际上是TBB和Poco之间的冲突.
我知道__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) 假设我有一个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)
原因是我不必创建另一种类型来包装begin,end因此我可以在 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) 我有两个接口IImporter和IExporter一个处理这些接口实例的类:
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或两者兼而有之.Add(...)调用中强制转换类型Add((IImporter) CsvIoInstance),因为这表明只使用了这种类型的导入器.但是两个重载都检查对象是否实现了两个接口并相应地将它添加到两个列表中.有没有办法以连贯的方式接受不同的类型(这样每个类型的调用看起来都一样)?
澄清我的实现:这是插件系统的一部分.我想添加多种方式来存储我的数据(以便其他应用程序可以使用它).该IExporter接口用于在IImporter接口加载数据时存储数据.该IoManager管理所有注册的插件.当然,一个类可以(并且可能是常见的)实现某种文件格式的导出和导入.这就是为什么我希望Add(...)函数在所有情况下都相似.
但是,再次考虑它(如评论中已经说明的那样)插件只在运行时才知道,这使得模糊性成为我认为的过时问题.所以这只适用于内置类型.
从聚合初始化,将指针设置为 struct member,以下代码合法:
struct S
{
int a;
int* aptr;
};
S s = { 3, &s.a };
Run Code Online (Sandbox Code Playgroud) c++ initialization object-lifetime language-lawyer aggregate-initialization
如何检查ITypeSymbol实例是否引用委托类型(如Action或Func<T>)。
我想我可以检查基本类型是否为System.Delegate. 这是正确的方法还是有更好的解决方案?
我只是在cppreference上阅读C++中的属性.他们在那里提到了可能的(真实)属性,现在我想知道它有什么好处.不幸的是,我无法在网上找到更多信息.
这是处理器在执行期间使用的某种分支预测吗?
以下代码被 clang 和 gcc 拒绝,但被 msvc 接受:
#include <iostream>
int main()
{
std::cout << unsigned long long(10);
}
Run Code Online (Sandbox Code Playgroud)
错误是
错误:“无符号”之前的预期主表达式
这应该编译,对吧?
以下代码无法编译:
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在这里返回左值引用?
这是一个完整的示例。
这是一个后续问题:当目标指针不是基类的类型时,为什么允许 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)
我期望这将编译,因为B和A在同一类型层次(B源自A)。在定义良好的程序中,类型指针A* …