我正在尝试实现以下概念
template<typename T>
concept GameLogic = requires(T a) {
typename T::StateType;
typename T::EventType;
{ a.initialState()->T::StateType }; // <-- relevant bit
};
Run Code Online (Sandbox Code Playgroud)
我想强制initialState()返回类型是同一类的嵌套类型。
概念定义不会引发错误(gcc 9.2),但以下实现GameLogic无法满足要求:
class SimpleGameLogic {
public:
using StateType = SimpleState;
using EventType = SimpleEvent;
StateType initialState() {
return _initialState;
}
private:
StateType _initialState;
};
Run Code Online (Sandbox Code Playgroud)
我已经尝试了上述语法的一些变体,但找不到正确的语法...或者这可能尚未实现?我究竟做错了什么?
我试图弄清楚如何为 sqr 运算编写“完全通用函数”(它实际上可以是乘法、除法、加法,并不重要)。
考虑下面的代码
#include <iostream>
struct A
{
int val = 2;
A() = default;
A(const A&) = delete; // To make sure we do not copy anything
A(A&& a) = delete; // To make sure we do not move anything
auto operator=(auto) = delete; // To make sure we do not assign anything
// This is important part, we do not want to create a new object on each multiplication.
// We want just to update the old …Run Code Online (Sandbox Code Playgroud) 在不借助 boost.iterator 等库的帮助下创建 C++20 之前的新迭代器时,有必要指定类型别名difference_type、value_type、pointer和。
根据cppreference ,对于 C++20,只需要指定和referenceiterator_categorydifference_typevalue_type这很棒!但是为什么这 3 个别名有默认值呢?
有两件事我不明白(其中一件事在我看来像是一个疏忽):
value_type为什么和没有默认值difference_type?使用类似的东西std::remove_reference_t<reference>作为默认值难道没有意义吗value_type?作为随机访问迭代器的默认设置difference_type,使用采用两个迭代器的运算符的结果类型可以说是有意义的-。contiguous_iterator_tag. 就像与input_iterator_tagvsforward_iterator_tag一样,我不明白编译器如何正确区分连续迭代器和随机访问迭代器,我想这就是它显然从不选择的原因contiguous_iterator_tag。这是故意的吗?将输入迭代器错误分类为前向迭代器似乎也有些危险,那么为什么不要求程序员自己指定此别名呢?iterator_category程序员已经明确声明了另一个类别,但默默地生成一个值是否是一个好主意,并且为iterator_category它生成一个与看起来完全不同的值concept也很奇怪。考虑这个不切实际的例子:#include <iostream>
#include <iterator>
// With the == operator, this is an input iterator, but nothing else.
struct WeirdIterator {
// Not an output iterator because …Run Code Online (Sandbox Code Playgroud) 考虑一个概念is_red,检查给定类型是否具有color设置为 的静态 cx 成员/*undefined*/::red,其中枚举中的`/ undefined /;
template <typename T>
concept is_red = requires(T) {
{ T::color == decltype(T::color)::red };
};
Run Code Online (Sandbox Code Playgroud)
这显然是错误的,因为它只检查合成是否定义良好。
因此,这不会按预期工作:
namespace apple {
enum colors{red, green, yellow };
struct granny_smith{
constexpr static auto color = colors::green;
};
}
static_assert(is_red<apple::granny_smith>); // should fail, but it does not using the previous concept implementation
Run Code Online (Sandbox Code Playgroud)
请参阅此处有关 godbolt 的实例。
这是我目前评估概念价值的方式:
template <bool condition>
using if_t = std::conditional_t<condition, std::true_type, std::false_type>;
template <typename T>
concept is_red …Run Code Online (Sandbox Code Playgroud) I'm trying to implement template function, for reading from byte array in big endian order. This is my current implementation:
template<typename T>
T load_big_endian(const unsigned char* buf) {
T res {};
std::size_t size = sizeof(T) - 1;
for (int i = 0; i <= size; i += 1) {
res |= static_cast<T>(buf[size - i] << (i * 8));
}
return res;
}
Run Code Online (Sandbox Code Playgroud)
Is this a good solution? Or better use a separate functions for each type, like load32_big_endian? And …
假设我们有一个简单的函数,它接受一个 std::chrono::time_point 并使用给定的格式化字符串返回一个字符串。像这样:
std::string DateTimeToString(std::chrono::sys_time, const char * szFormat /*= "%Y/%m/%d %H:%M:%S"*/)
Run Code Online (Sandbox Code Playgroud)
根据std::formatter的 cppreference 文档,我们应该能够使用各个标签来创建像2021/03/24 15:36:32.123123. 但是,当 time_point 的持续时间使用微秒(我们必须使用)时,这将引发 format_error。
如果我们将其拆分为单独的调用,以便我们分别使用日期和时间的格式,那么它就可以工作。像这样:
auto tSysTime = std::chrono::system_clock::now();
std::string sTime = std::format("{:%H:%M:%S}", tSysTime.time_since_epoch());
std::string sDate = std::format("{:%Y/%m/%d}", std::chrono::sys_days(std::chrono::duration_cast<std::chrono::days>(tSysTime.time_since_epoch())));
Run Code Online (Sandbox Code Playgroud)
我是否误解了某些东西,或者没有办法为我的目的使用单一格式字符串?请记住,格式字符串是一个可选参数,因此我无法对单个参数的拆分进行硬编码。
我的期望是写
std::format("{:%Y/%m/%d %H:%M:%S}",tSysTime.time_since_epoch());
Run Code Online (Sandbox Code Playgroud)
然而,这崩溃了......
预先感谢您的任何帮助!
编辑:我在 Visual Studio 2019 中使用 /std::c++latest 标志
如果我们有一个这样的枚举类
enum class alpha{ a, b, c, d};
Run Code Online (Sandbox Code Playgroud)
是否可以实现一个运算符,在字母表中的字母之间建立排序关系,使得
enum class alpha{ a, b, c, d};
constexpr auto operator <=> (alpha lhs, alpha rhs)
{
//how do we achieve this?
};
#include <gtest/gtest.h>
TEST(alphabet, allows_ordering_comparison)
{
EXPECT_TRUE(alpha::a < alpha::b);
}
Run Code Online (Sandbox Code Playgroud)
小于比较将评估为真。我对此的平庸理解是 enum 是一种偏序。对代码中的错误表示歉意。考虑这个问题
我有以下代码,它可以工作,但是 C++20 版本看起来并不比 C++17 版本好多少。我的猜测问题是multimap equal_range返回 apair并且范围无法确定这是一对有效的迭代器。
有没有办法用更短更好的方式来写这个?
#include <iostream>
#include <map>
#include <ranges>
int main() {
std::multimap<bool,int> oddness{{false,2}, {true,3}, {true,47}, {false,74656}};
// nice, does not work:
// oddness.equal_range(true) | std::views::values;
// works:
oddness | std::views::values;
// working code:
auto odds = oddness.equal_range(true);
const auto odds_view = std::views::values(std::ranges::subrange(odds.first, odds.second));
for (const auto& odd : odds_view) {
std::cout << odd << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的代码示例。我可以在 C++17 中编译它,但不能在 C++20 中编译它。为什么不?
struct S
{
S(const S&) = delete;
S( S&& ) = default;
int k;
int m;
int n;
};
int main()
{
S s1{10, 20, 30};
return s1.m;
}
Run Code Online (Sandbox Code Playgroud) c++ ×10
c++20 ×10
c++-concepts ×2
c++-chrono ×1
c++14 ×1
c++17 ×1
enums ×1
format ×1
iterator ×1
standards ×1
std-ranges ×1
string ×1
vector ×1