在https://en.cppreference.com/w/cpp/concepts/same_as上查看same_as概念的可能实现,因为我注意到正在发生奇怪的事情。
namespace detail {
template< class T, class U >
concept SameHelper = std::is_same_v<T, U>;
}
template< class T, class U >
concept same_as = detail::SameHelper<T, U> && detail::SameHelper<U, T>;
Run Code Online (Sandbox Code Playgroud)
第一个问题是为什么要插入一个SameHelper概念?第二个就是same_as检查是否T相同U和U一样T?这不是多余的吗?
考虑以下代码:
struct A
{
// No data members
//...
};
template<typename T, size_t N>
struct B : A
{
T data[N];
}
Run Code Online (Sandbox Code Playgroud)
这就是你必须如何初始化 B:B<int, 3> b = { {}, {1, 2, 3} };
我想避免基类不必要的空 {}。Jarod42 here提出了一个解决方案,但是,它不适用于元素默认初始化:B<int, 3> b = {1, 2, 3};很好,但B<int, 3> b = {1};不是:b.data[1]并且b.data[2]没有默认初始化为 0,并且会发生编译器错误。有什么方法(或者 C++20 会有)从构造中“隐藏”基类?
According to cppreference, std::copyable is defined as follows:
template <class T>
concept copyable =
std::copy_constructible<T> &&
std::movable<T> && // <-- !!
std::assignable_from<T&, T&> &&
std::assignable_from<T&, const T&> &&
std::assignable_from<T&, const T>;
Run Code Online (Sandbox Code Playgroud)
I'm wondering why a copyable object should be also movable. Just think about a global variable that is accessed by several functions. While it makes sense to copy that variable (for example to save its state before calling another function) it makes no sense, and actually would be …
在我的平台上(以及我认为的大多数平台上)std::size_t并且std::ptrdiff_t 具有相同的大小和相同的对齐方式。有没有哪个平台不是真的?简而言之:标准是否要求?
是否定义了此代码的行为?
int* ptr = new int[10];
operator delete[] (ptr, 0);
Run Code Online (Sandbox Code Playgroud)
这段代码可以正常编译,并且(在我的机器上)似乎什么也没有发生。它的行为在某处定义吗?
由于 C++20 二进制补码表示是标准允许的唯一表示,保证范围从 -2 N-1到 +2 N-1 -1。因此,对于 64 位有符号整数类型,范围从-9'223'372'036'854'775'808到9'223'372'036'854'775'807。但是,此代码不能在 Visual Studio 上编译(也不能在 gcc 上编译)
int main()
{
long long x{-9'223'372'036'854'775'808LL};
// error C4146: unary minus operator applied to unsigned type, result still unsigned
// error C2397: conversion from 'unsigned __int64' to '__int64' requires a narrowing conversion
}
Run Code Online (Sandbox Code Playgroud)
然而,如果我用long long x{-9'223'372'036'854'775'807LL - 1}compiles替换代码就好了并x保持正确的值。我没有得到什么?
考虑以下代码:
template<typename...>
struct C
{ /* ... */ };
template<typename T, unsigned N>
struct B
{
using type = /* ... */;
};
template<size_t N, typename... Ts>
struct A
{
using type = C<typename B<Ts, N-->::type...>; // decrement N sizeof...(Ts) times
};
Run Code Online (Sandbox Code Playgroud)
所以例如
typename A<5, int, long, void>::type
Run Code Online (Sandbox Code Playgroud)
扩展到
C<typename B<int, 5>::type, typename B<long, 4>::type, typename B<void, 3>::type>
Run Code Online (Sandbox Code Playgroud)
由于N是一个const值,此代码无法编译。有没有其他办法?