问题标题的措辞可能不正确,我会很乐意根据您的建议进行修复。
我的问题可以用这个片段来说明:
#include <array>
template <typename Callable>
constexpr auto make_array_ok(Callable callable) {
return std::array<int, callable()>{};
};
// constexpr auto make_array_bad(std::size_t s)
// {
// return std::array<int,s>{};
// };
int main(int argc, char**) {
static_cast<void>(argc);
auto size = []() { return std::size_t{42}; };
// fails to compile -- as I expected
// auto size_dyn = [argc]() { return std::size_t(argc); };
// auto a = make_array_ok(size_dyn);
// also fails to compile -- but why?
// auto size_capt = [arg = size()]()constexpr{return arg;}; …Run Code Online (Sandbox Code Playgroud) 在C++ Weekly - Ep 313 -constexpr我花了 5 年时间才解决的问题!Jason Turner 演示了几种编译时技术,以便std::string在编译时构造 a,然后将其传递给 astd::string_view以在运行时使用。
核心问题是,std::string使用new编译时构造的std::string必须在单个表达式中使用,因为在相同的表达式中new必须有相应的(抱歉近似的措辞)。deleteconstant/compile-time context
由于代码很长,我把它放在问题的最后。
为了做到这一点,他首先展示了如何通过将数据保存在函数内部来std::string将数据从 复制到 an (我目前不确定它是否只能通过函数来实现)。std::arrayconstevalconstexpr
我完全不明白的是,他如何使用非类型模板参数std::array(NTTP)将立即函数调用的生命周期“延长”到大约 19 分钟。
我对标准的理解(可能是错误的)是 NTTPtemplate parameter object与静态存储持续时间相关联:
命名类类型 T 的非类型模板参数的 id 表达式表示类型为 const T 的静态存储持续时间对象,称为模板参数对象,它与模板参数等价([temp.type])对应的模板参数已转换为模板参数的类型([temp.arg.nontype])。没有两个模板参数对象是模板参数等效的。
然而我尝试使用一个更简单(且人为的)示例:
template <auto Value>
consteval const auto& make_static() {
return Value;
}
int main() {
[[maybe_unused]] …Run Code Online (Sandbox Code Playgroud) 我想知道如何std::bit_cast以明确定义的方式使用,特别是在存在不确定位的情况下。什么时候是std::bit_cast使用定义的行为,什么时候是未定义的行为?
因此,我需要澄清cppreference 关于 std::bit_cast的措辞。我不明白下面这段话的意思:
对于不确定结果的值表示中的每一位,包含该位的最小对象具有不确定值;除非该对象是 unsigned char 或 std::byte 类型,否则行为未定义。结果不包含任何不确定的值。
当输入 ( ) 包含不确定位(明显是填充位)时,所提到的对象是什么以及它们的类型(与其他类型)From的区别是什么?std::byte
让我们写一个例子(不是实际的用例,只是说明具有不确定位的情况):
#include <bit>
#include <cstdint>
struct S40 {
std::uint8_t a = 0x51;
std::uint32_t b = 0xa353c0f1;
};
struct S3 {
std::uint8_t a : 3;
};
int main() {
S40 s40;
std::uint64_t a64 = std::bit_cast<std::uint64_t>(s40);
// (3) on tested compilers, a64 is 0xa353c0f1UUUUUU51 where U is undefined byte
S3 s3;
s3.a = 0b101;
std::uint8_t a8 = std::bit_cast<std::uint8_t>(s3);
// (4) …Run Code Online (Sandbox Code Playgroud) 据我所知,MSVC告诉编译器使用特殊可用指令的编译选项是/arch。在 clang/linux 上,我们可以使用 -march=native 来自动检测架构和“最佳”指令集。
有没有办法用 /arch 实现同样的效果,即在当前硬件上找到此选项的最佳可用参数?
我在 MSVC 文档中找不到合适的选项。如果不存在,是否有其他解决方案(例如通过 CMake)?
c++ compilation cpu-architecture compiler-optimization visual-c++
virtual我对我读到的有关混合和constexpr成员函数的内容感到困惑。根据:
直到 C++17 为止,应该不可能混合constexpr和virtual(标准在上面的链接中引用)
然而我设计了这个简单的例子:
#include <cstddef>
struct SizedObject {
virtual size_t GetSize() const = 0;
};
struct DynSizedObject : public SizedObject {
size_t s;
size_t GetSize() const override final { return s; }
};
struct StatSizedObject : public SizedObject {
const size_t s;
constexpr size_t GetSize() const override final { return s; }
constexpr explicit StatSizedObject(const size_t i) : s(i) {}
};
int …Run Code Online (Sandbox Code Playgroud) 我有一个与下面的代码片段非常相似的代码:
#include <vector>
struct dummy
{
std::vector<int> const data;
dummy() = default;
};
Run Code Online (Sandbox Code Playgroud)
大多数编译器都毫无问题地接受此代码,但clang版本 9 至 14 除外:
警告:显式默认的默认构造函数被隐式删除 [-Wdefaulted-function-deleted]
注意:“dummy”的默认构造函数被隐式删除,因为 const 限定类型“const std::vector”的字段“data”不会被初始化
问题clang 15再次消失。
居住
注意,如果const删除,错误也会消失。
然而我希望data被初始化为一个const空向量。
这是一个clang错误吗?否则,为什么这段代码被拒绝(为什么其他编译器不抱怨)?
我正在审查一个非编译代码,其中我发现了与此类似的设计:
巴赫
#include <memory>
class A;
class B {
private:
int val;
// pImpl idiom
std::unique_ptr<A> pImpl;
constexpr B(int x): val(x){};
virtual ~B();
};
Run Code Online (Sandbox Code Playgroud)
析构函数是在 中定义的B.cpp,但构造函数是constexpr它意味着它是在 中定义的B.h。但是编译失败,因为编译器需要有一个 的构造函数A,此时它是一个不完整的类型。但我认为这constexpr是一个设计错误,因为我看不到如何B在编译时使用实现来构造 a 。
因此,constexpr在这种情况下是错误的,还是有办法B在编译时构造 a (我不认为std::unique_ptr可以在编译时构造,除了 from nullptr)?
注意我试图将构造函数定义推入内部,B.cpp但是链接器然后(从逻辑上我认为)触发了构造函数上的未定义引用...
注意编译到目前为止仅在 msvc 上进行了测试注意
我读了一堆关于 pimpl 的帖子并且unique_ptr(它们是很多)但我可能错过了一个足够的问题,而且问题很可能是重复的......
我正在尝试在代码块 IDE 中成为明星。为了创建星星,我尝试合并“ \”反斜杠,但是当我构建并运行程序时,反斜杠被省略。
#include <iostream>
int main() {
std::cout << " /\\ " << '\n';
std::cout << "< >" << '\n';
std::cout << "//\\" << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在网上查找了一个解决方案,建议使用两个反斜杠,因为反斜杠是一个“可执行文件”(定义可能错误)。该解决方案确实适用于第一行,但星形的末端缺少一条腿,有什么想法为什么吗?
我还尝试了最后一行的三重反斜杠,但我遇到了同样的问题。
c++ ×9
c++20 ×2
compilation ×2
bit-cast ×1
clang++ ×1
codeblocks ×1
compile-time ×1
console ×1
constexpr ×1
escaping ×1
godbolt ×1
iostream ×1
non-type-template-parameter ×1
pimpl-idiom ×1
unique-ptr ×1
virtual ×1
visual-c++ ×1