我有一个模板课
template<typename EventT, typename StateT, typename ActionT, bool InjectEvent = false, bool InjectStates = false, bool InjectMachine = false>
class StateMachine;
Run Code Online (Sandbox Code Playgroud)
和它的专业化
template<typename EventT, typename StateT, typename ActionResultT, typename ...ActionArgsT, bool InjectEvent, bool InjectStates, bool InjectMachine>
class StateMachine<EventT, StateT, ActionResultT(ActionArgsT...), InjectEvent, InjectStates, InjectMachine>
Run Code Online (Sandbox Code Playgroud)
专业化用于将函数类型解析为其返回值和参数类型。
该类的实现按预期工作,并通过了所有测试。
如果我默认值添加到ActionT通过使ActionT = void(),Visual Studio中抱怨“式的StateMachine <...>是不完整的”智能感知和停止工作(至少对于这种类型的所有实例)。但是,代码会像以前一样通过编译并通过所有测试(我还有一个测试明确使用默认参数)。
这是Visual Studio中的错误,还是我错过了什么?
我正在使用VS 2015 Pro和C ++ 14。
编辑
这是一个最小的工作示例:
#include <iostream>
#include <functional>
using namespace std;
template<typename EventT, typename StateT, typename ActionT = void(), bool InjectEvent …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 UserControl 中使用设计时 DataContext。根据这篇文章(以及本网站上的一些帖子),应该可以在 UserControl 标记本身中使用设计时 DataContext。
但是它对我不起作用,无论是在 UserControl 的还是在根元素的标签中。
UserControl(和模型视图模型)非常简单。一堆原始类型绑定到一些文本块和滑块。
我的用户控件看起来像:
<UserControl mc:Ignorable="d"
d:DataContext="{d:DesignInstance mockups:PrototypeMockup}">
<GroupBox DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=Prototype}" Header="{Binding Name}" >
...
<Image Source="{Binding Image}" />
<TextBlock Text="{Binding Size, StringFormat={}{0} mm}" />
<Slider Minimum="10" Maximum="80" Value="{Binding Size}" IsEnabled="{Binding IsEditing}" />
<TextBlock Text="{Binding Threshold}" />
<Slider Minimum="0" Maximum="255" Value="{Binding Threshold}" IsEnabled="{Binding IsEditing}" />
<TextBlock Text="{Binding BlockSize, StringFormat={}{0} px}" />
<Slider Minimum="10" Maximum="200" Value="{Binding BlockSize}" IsEnabled="{Binding IsEditing}" />
...
Run Code Online (Sandbox Code Playgroud)
模型视图模型如下所示:
public class PrototypeMockup
{
public string …Run Code Online (Sandbox Code Playgroud) 我有一个具有固定大小和可变文本的 TextBlock。我希望我的文本始终适合 TextBlock(没有省略号或溢出,但有自动换行)。如果文本发生变化,应调整字体大小,使文本适合 TextBlock 的边界。
我知道我可以将 TextBlock 打包到一个 Viewbox 中(我目前正在这样做),但我没有自动换行。
上图显示了三个不同的 TextBlock(蓝色数字仅用于说明)。如果我使用 Viewbox,我会得到类似 1 和 2 的结果,但我更希望得到类似 1 和 3 的结果。
所以我基本上是在尝试将 Viewbox 和自动换行结合起来。如何才能做到这一点?
在C++中为函数类型声明类型别名时,被认为是最佳或良好的做法(我知道这部分问题可能是主观的)?或
using FuncType = void(int, int);
Run Code Online (Sandbox Code Playgroud)
要么
using FuncType = std::function<void(int, int)>;
Run Code Online (Sandbox Code Playgroud)
一个人比另一个人有好处吗?
例如,我应该如何使用这些类型作为函数参数(当作为函子,lambda,成员或全局函数传递时)
void foo(FuncType&& func) { ... }
void foo(FuncType func) { ... }
void foo(std::function<FuncType> func) { ... }
Run Code Online (Sandbox Code Playgroud)
编辑
我知道上面的所有例子都不适用于#1和#2,但这不是重点.我想知道哪个(以及为什么)选项更好,在将它用作函数参数时应该如何传递此类型.
由于它看起来太宽泛(我完全理解),我将提供有关我的具体案例的更多细节.
我有一个类,它包含我想要调用的函数向量(最可能是并行的,但我认为这不重要).在这个类中,我可以在运行时向向量添加函数.
例如:
类
Container
{
public:
using FuncType = std::function<void(const SomeComplexDataType&, int, double)>;
inline void addFunction(FuncType func)
{
_funcs.push_back(func);
}
inline void call(const SomeComplexDataType& a, int b, double c)
{
for (auto& func : _funcs)
func(a, b, c);
}
private:
std::vector<FuncType> _funcs{};
};
struct …Run Code Online (Sandbox Code Playgroud) 对于模糊的标题感到抱歉,但我无法想出一个更好的标题.
我写了一个扁平化容器的函数:
template <typename Container, typename OutIt>
void flatten(const Container& container, OutIt res)
{
if constexpr (std::is_convertible_v<typename Container::value_type, typename std::iterator_traits<OutIt>::value_type>)
{
for (const auto& value : container)
{
*res = value;
++res;
}
}
else
{
for (const auto& subContainer : container)
flatten(subContainer, res);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望它像以下一样使用:
vector<vector<int>> test = {{1}, {2, 3, 4}, {5, 6}, {7}};
vector<int> res;
flatten(test, std::back_inserter(res));
Run Code Online (Sandbox Code Playgroud)
这应该基本上是从复制所有嵌套值test到res,这样res == { 1, 2, 3, 4, 5, 6, 7 }.
但是,如果我想编译代码,编译器会抛出一些错误,基本上说,else …
我已经在github上问了这个问题(大约一个月前),没有任何答案,所以我现在在这里问。
我在项目中使用Cereal作为序列化库。我尝试添加序列化功能std::string_view(基本上是从std::string实现中复制和粘贴)。但是,Cereal会引发编译器错误:
谷物找不到提供的类型和档案组合的任何输出序列化功能。
这是我的实现(我在这里禁用了反序列化,但是我也尝试了一个伪函数,它给了我相同的结果):
#pragma once
#include "../cereal.hpp"
#include <string_view>
namespace cereal
{
//! Serialization for basic_string_view types, if binary data is supported
template <class Archive, class CharT, class Traits>
typename std::enable_if<traits::is_output_serializable<BinaryData<CharT>, Archive>::value, void>::type
CEREAL_SAVE_FUNCTION_NAME(Archive& ar, std::basic_string_view<CharT, Traits> const& str)
{
// Save number of chars + the data
ar(make_size_tag(static_cast<size_type>(str.size())));
ar(binary_data(str.data(), str.size() * sizeof(CharT)));
}
//! Deserialization into std::basic_string_view is forbidden due to its properties as a view.
//! However std::basic_string_view can be deserialized …Run Code Online (Sandbox Code Playgroud) 鉴于类型
struct S
{
int x;
};
Run Code Online (Sandbox Code Playgroud)
和两个函数
S* f()
{
const auto x = new S[1] { { 42 } };
return x;
}
S* g()
{
const auto x = new S[1];
x[0] = {42};
return x;
}
Run Code Online (Sandbox Code Playgroud)
人们会认为f和g行为相同。根据这个答案 f应该执行聚合初始化,x这将导致相同的行为。纵观组装铛的和gcc这似乎是真实的,并都f和g产生完全相同的组件。
但是,我猜 msvc 不想这样做。msvc for 的汇编g类似于 clang 和 gcc,但f它似乎完全忽略了初始化程序:
S * f(void) PROC ; f, COMDAT
mov ecx, 4
jmp void * operator …Run Code Online (Sandbox Code Playgroud) msvc 的 cpp 核心指南代码分析器告诉我
警告 C26472 不要使用 a
static_cast进行算术转换。使用大括号初始化,gsl::narrow_cast或gsl::narrow(type.1)。
对于这个片段
static_cast<IntType>(static_cast<unsigned long long>(hexValue(digit)) << (digitIdx * 4));
Run Code Online (Sandbox Code Playgroud)
为什么我不应该在这里使用 static_cast ?
另外,使用大括号初始化,这看起来像这样
IntType{unsigned long long{hexValue(digit)} << (digitIdx * 4)};
Run Code Online (Sandbox Code Playgroud)
我认为这看起来并没有更好。这看起来更像是函数风格的转换而不是其他任何东西。
我无法使用 gsl 并且我认为gsl::narrow它是自身的包装器static_cast,所以这纯粹是一个可读性问题吗?
我知道关于这个主题有几个问题,但请听我说完。
我知道我们可以在未评估的上下文中使用无捕获的 lambda(例如decltype),但是捕获的 lambda 又如何呢?
我在当前的 C++ 标准中找不到任何内容表明这是自 C++20 以来的一个问题,但我绝不是语言律师。
但我看到的是,主要编译器的结果有所不同。
这些概念有效吗?
template <typename T>
concept C1 = requires { []{}; };
template <typename T>
concept C2 = requires(T t) { [&t]{}; };
Run Code Online (Sandbox Code Playgroud) 给定以下类型:
struct A
{
std::vector<std::string> vec;
using reference = std::iterator_traits<decltype(vec)::iterator>::reference;
using const_reference = const reference;
};
Run Code Online (Sandbox Code Playgroud)
为什么reference == const_reference?为什么const限定符会在第二个类型别名中删除?
请参阅godbold上不应编译的示例.
我有一个模板化的类,它将一堆迭代器(-types)作为模板参数.从这些迭代器我需要推导出引用和const引用类型,因为我有一些成员函数,如:
struct A
{
std::vector<std::string> vec;
using reference = std::iterator_traits<decltype(vec)::iterator>::reference;
using const_reference = const reference;
const_reference foo() const
{
return vec[0];
}
};
Run Code Online (Sandbox Code Playgroud)
通过删除const限定符,我实际上返回了一个foo非法的引用,因为它是一个const成员函数,所以编译器抛出.
c++ ×8
c++17 ×4
c# ×2
wpf ×2
xaml ×2
c++20 ×1
cereal ×1
clang ×1
constexpr ×1
design-time ×1
gcc ×1
intellisense ×1
qualifiers ×1
visual-c++ ×1