使用 C++20'sconcept我注意到这std::unique_ptr似乎无法满足这个std::equality_comparable_with<std::nullptr_t,...>概念。从std::unique_ptr的定义来看,它应该在 C++20 中实现以下内容:
template<class T1, class D1, class T2, class D2>
bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, std::nullptr_t) noexcept;
Run Code Online (Sandbox Code Playgroud)
这个要求应该实现对称比较nullptr——根据我的理解,这足以满足equality_comparable_with.
奇怪的是,这个问题似乎在所有主要编译器上都是一致的。以下代码被 Clang、GCC 和 MSVC 拒绝:
// fails on all three compilers
static_assert(std::equality_comparable_with<std::unique_ptr<int>,std::nullptr_t>);
Run Code Online (Sandbox Code Playgroud)
然而,同样的断言与std::shared_ptr被接受:
// succeeds on all three compilers
static_assert(std::equality_comparable_with<std::shared_ptr<int>,std::nullptr_t>);
Run Code Online (Sandbox Code Playgroud)
除非我误解了什么,否则这似乎是一个错误。我的问题是这是否是三个编译器实现中的巧合错误,还是 C++20 标准中的缺陷?
注意:如果这恰好是一个缺陷,我会标记这个语言律师 …
根据 C++ 标准,将指向固定数组(例如T(*)[N]或T(&)[N])的指针或引用转换为指向相同类型和 CV 限定(例如T(*)[M]或T(&)[M])的较小固定数组的指针或引用是否合法?
基本上,对于T(无论布局类型)的所有实例化,这是否总是格式良好的:
void consume(T(&array)[2]);
void receive(T(&array)[6])
{
consume(reinterpret_cast<T(&)[2]>(array));
}
Run Code Online (Sandbox Code Playgroud)
我没有看到任何对这是有效转换的引用:
然而,似乎所有主要编译器都接受这一点并生成正确的代码,即使在使用T = std::string( compiler explorer)时进行了优化(如果它是未定义的行为,这证明不是很多)。
我的理解是,根据类型系统,这应该是非法的,因为T[2]从未真正创建过对象,这意味着对的引用T(&)[2]将是无效的。
我将这个问题标记为c++11,因为这是我对答案最感兴趣的版本,但我很想知道这个答案在较新版本中是否有所不同。
我正在尝试实现一个私有子例程来将Sheet添加到活动工作簿(正在使用Sheet,以便可以选择添加xlForms,xlWorksheet等).
但是我有一个奇怪的问题,即相对于工作簿中的其他工作表创建新图表的位置.
我首先删除同名表(如果存在),然后使用以下代码:
ActiveWorkbook.Sheets.Add(After:=Sheets(Sheets.count()), _
Type:=sheet_type).Name = sheet_name
Run Code Online (Sandbox Code Playgroud)
sheet_type枚举的可选参数在哪里XlSheetType,sheet_name是a string.
它对于每个可用的参数都是完全正常的,例如xlWorksheet,xlDialogSheet甚至是xl4MacroSheet- 但由于某种原因,它会xlChart在结束之前创建1位置,而不是将它作为工作簿中的最后一个表单.
所以样本I/O(仅从3张开始):
> Create_Sheet "Test", sheet_type:=xlWorksheet
Sheet 1 | Sheet 2 | Sheet 3 | Test
> Create_Sheet "Test", sheet_type:=xlDialogSheet
Sheet 1 | Sheet 2 | Sheet 3 | Test
> Create_Sheet "Test", sheet_type:=xlChart
Sheet 1 | Sheet 2 | Test | Sheet 3
Run Code Online (Sandbox Code Playgroud)
Sheets.count()在前面的例子中正确地返回3(因为我只从表格1,2和3开始),因此它应该假设在第三张表格之后定位,但事实并非如此.尝试Sheets.count() + 1进行测试只会给我一个超出范围运行时异常的数组下标(这是预期的).
我甚至只测试了基本代码:
ActiveWorkbook.Sheets.Add(After:=Sheets(Sheets.count()), _
Type:=xlChart).Name = …Run Code Online (Sandbox Code Playgroud) 我正在尝试键入擦除一个对象并遇到一个问题,我希望有人在这里可能有专业知识.
我没有遇到任何类型的问题 - 擦除任意非模板化函数; 到目前为止,我一直在做的是创建一个自定义的static
"虚拟表" - 函数指针的集合.这都是使用非捕获lambda进行管理的,因为它们会衰减为自由函数指针:
template<typename Value, typename Key>
class VTable {
Value (*)(const void*, const Key&) at_function_ptr = nullptr;
// ...
template<typename T>
static void build_vtable( VTable* table ) {
// normalizes function into a simple 'Value (*)(const void*, const Key&)'' type
static const auto at_function = []( const void* p, const Key& key ) {
return static_cast<const T*>(p)->at(key);
}
// ...
table->at_function_ptr = +at_function;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
(为简洁起见,省略了更多辅助函数/别名)
遗憾的是,这种方法与功能无关template.
我希望类型擦除类具有类似于以下内容的东西:
template<typename …Run Code Online (Sandbox Code Playgroud) clang当使用和选项进行交叉编译时-target,针对与本机系统相同的体系结构和硬件,我注意到对于三元组中的 是 的clang情况,似乎会产生比本机构建的对应部分更糟糕的优化。<sys>none
考虑这个简单的代码示例:
int square(int num) {
return num * num;
}
Run Code Online (Sandbox Code Playgroud)
当-O3使用进行优化时-target x86_64-linux-elf,本机x86_64目标代码生成结果为:
square(int):
mov eax, edi
imul eax, edi
ret
Run Code Online (Sandbox Code Playgroud)
生成的代码的-target x86_64-none-elf产量:
square(int):
push rbp
mov rbp, rsp
mov eax, edi
imul eax, edi
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
尽管具有相同的硬件和优化标志,但显然有些东西缺少优化。尽管没有使用特定于系统的功能,但如果在目标三元组中none替换为,问题就会消失。linux
乍一看,它可能看起来根本没有优化,但不同的代码段表明它正在执行一些优化,但不是全部。例如,循环展开仍在发生。
尽管上面的示例只是使用 x86_64,但实际上,这个问题正在为armv7基于 的受限嵌入式系统生成代码膨胀,并且我注意到在某些情况下存在一些错过的优化,例如:
add指令中(在类似-Os …编写 docker 文件以针对同一编译器的许多不同版本进行构建的惯用方法是什么?
我有一个项目,它针对不同编译器的各种版本进行测试,就像gccCIclang工作的一部分一样。在某些时候,CI 任务的代理被更新/更改,导致新的作业失败——因此我开始研究对这些构建进行 docker 化,以尝试保证更好的可靠性和稳定性。
然而,我很难理解什么是正确且惯用的方法来生成这样的构建图像,而不会导致层引起的大量重复。
例如,假设我想使用以下工具集进行构建:
gcc4.8、4.9、5.1、...(各种版本)cmake(最新的)ninja-build我可以写这样的东西:
# syntax=docker/dockerfile:1.3-labs
# Parameterizing here possible, but would cause bloat from duplicated
# layers defined after this
FROM gcc:4.8
ENV DEBIAN_FRONTEND noninteractive
# Set the work directory
WORKDIR /home/dev
COPY . /home/dev/
# Install tools (cmake, ninja, etc)
# this will cause bloat if the FROM layer changes
RUN <<EOF
apt update
apt install -y cmake ninja-build
rm -rf /var/lib/apt/lists/*
EOF …Run Code Online (Sandbox Code Playgroud) 这个问题可能有点主观,但我只是想按照最好的编程实践来组织代码.
我有一个类Polynomial,它引用了很多类Rational,并且在许多不同的方法中,它使用一个Rational等于1,0或-1的值进行比较.
因此,我定义了以下常量:
public static final Rational ZERO = new Rational(0);
public static final Rational ONE = new Rational(1);
public static final Rational NEG_ONE = new Rational(-1);
Run Code Online (Sandbox Code Playgroud)
但是,我不确定的是在哪里以有意义的方式存储这些值.
一方面,Polynomial使用它们的是什么,因此将它们存储在类中将它本地化到它将被使用的位置.这也意味着它可以更改为private,以便仅在一个类中使用.
在另一方面,如果内部定义Rational,然后到值的所有通话变得Rational.ZERO,Rational.ONE,Rational.NEG_ONE-这使得它非常可读的,并组织其在词汇理解的方式.它还提供了定义类似常量的机会,Polynomial如果需要的话.
所以基本上,除了意见之外,组织在这样的事情中最常见的做法是什么?我的想法是否适合它的任何一个位置,还是有其他解决方案我没有考虑过?
我知道 C++11 样式属性支持以命名空间为前缀的特定于供应商的属性。GCC 和 Clang 都支持带有前缀gnu::(gcc 和 clang)或clang::(仅 clang)的各种属性,它们对应于等效__attribute__((...))语法。
MSVC 属性的文档表明它支持标准属性以及gsl::属性,但没有提及__declspec属性的向后兼容性。
我希望__declspec(noinline)有类似的属性表示[[msvc::noinline]]- 但我似乎找不到任何关于此的文档。
所以我的问题是,MSVC 是否支持__declspecC++11 样式属性?
如果没有,会有人知道他们没有吗?C++ 属性的最初原理是抽象各种特定于编译器的__attribute__特性__declspec,因此如果在标准化 9 年后仍然不支持它,那就很奇怪了。
C++20 引入了新的太空船运算符<=>,它允许根据三向比较的排序强度来合成相等和比较运算符。
然而,当使用以下简单的玩具示例执行异构比较时,它似乎无法合成相等运算符 - 但仍然成功合成排序运算符 - 尽管具有std::strong_ordering:
#include <compare>
#include <cassert>
template <typename T>
struct Wrapper {
int value;
auto operator<=>(const Wrapper&) const = default;
template <typename U>
auto operator<=>(const Wrapper<U>& other) const {
return value <=> other.value;
}
};
void test() {
// Same type equality -- works
assert(Wrapper<Foo>{42} == Wrapper<Foo>{42});
// Heterogeneous comparison -- works
assert(Wrapper<Foo>{42} < Wrapper<Bar>{45});
// Heterogeneous equality -- doesn't work?
assert(Wrapper<Foo>{42} == Wrapper<Bar>{42});
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 上,这会出现以下错误:
<source>: In function …Run Code Online (Sandbox Code Playgroud) 在C ++中,它是合法的char,unsigned char或std::byte指向别名任何T指针。这种别名指针能够访问原始内存中的对象表示。
我的问题是它是否是合法的和游离的未定义的行为,以使用一个T*从算术上派生的指针char/ unsigned char/std::byte指针混叠的原始T阵列对象序列-前提条件是所得指针仍然正确地对准和混叠序列的原始可达性内. 作为一个具体的例子:
// Array sequence is 2 in length
auto array = std::array<unsigned,2>{0xdead, 0xbeef};
// Derive the address of &array[1] using std::byte pointer
auto p = reinterpret_cast<std::byte*>(array.data());
auto p1 = reinterpret_cast<unsigned*>(p + sizeof(unsigned));
assert(p1 == &array[1]); // This expression should be legal since the pointer is safely derived
assert(*p1 == array[1]); // But is this legal, …Run Code Online (Sandbox Code Playgroud) c++ ×8
c++20 ×2
arrays ×1
c++-concepts ×1
c++11 ×1
c++14 ×1
clang ×1
docker ×1
dockerfile ×1
excel ×1
excel-vba ×1
java ×1
ms-office ×1
office-2007 ×1
optimization ×1
organization ×1
pointers ×1
templates ×1
type-erasure ×1
vba ×1
visual-c++ ×1