我正在尝试分析项目的构建时间,以便了解什么花费了最多的时间。这看起来应该很容易......如果我有一切clang在文件中列出了每个命令,我可以对每个命令进行计时并按时间排序以找到花费最长的编译,然后我可以进去看看哪些编译单位感到惊讶并试图找出为什么他们这么慢。
谷歌搜索对此一无所获。显然这是可能的并且很有用。
所以,要么:
或者
clang它想要运行的所有命令的列表?CXX_COMPILER_LAUNCHER?我有一个包含成员的班级std::vector<FwdDecl>。我想做
extern template class std::vector<FwdDecld>;
Run Code Online (Sandbox Code Playgroud)
在标题和
template class std::vector<FwdDecld>;
Run Code Online (Sandbox Code Playgroud)
所以.cpp我的类的特殊成员函数可以是自动的(而不是在 中声明所有六个.h并=default在 中声明所有六个.cpp)。
这似乎适用于 MSVC 和 Apple Clang,但不适用于 Clang 或 GCC: https: //godbolt.org/z/Tc8G91rj6
不过,这适用于boost::container::vector: https: //godbolt.org/z/j6zfj4K3r
它是否正确?GCC 和 Clang 合规吗?是MSVC吗?
相关extern template class std::unique_ptr<FwdDecl>似乎确实有效(尽管显然它不可复制),即使前向声明的类是私有的: https: //godbolt.org/z/ThhW4fPGE
由于隐式转换以及std::numeric_limits<T>::max()and Friends 返回 type 的事实,编写一个在概念上“做正确的事情”的T函数似乎并不简单。也就是说,如果它们共享公共范围,则进行比较,如果不是,则确定是否小于,无论位数或符号性如何。有没有比这个简单的实现更简单的实现?:bool cmp(IntA a, IntB b)return a < b;ab
template <typename IntA, typename IntB>
[[nodiscard]] constexpr bool cmp(IntA a, IntB b) noexcept {
static_assert(std::is_integral_v<IntA>);
static_assert(sizeof(IntA) <= sizeof(long long int), "We assume we can fit everything into long long");
static_assert(std::is_integral_v<IntB>);
static_assert(sizeof(IntB) <= sizeof(long long int), "We assume we can fit everything into long long");
if (a < 0) {
if (b < 0) {
return static_cast<signed long long int>(a) < …Run Code Online (Sandbox Code Playgroud) 以下证据表明:
inline
constexpr std::size_t prev(std::size_t i) {
--i;
return i;
}
int main() {
static const std::size_t i = 0;
static_assert(prev(i) == std::size_t(-1), "Decrementing should give std::size_t(-1)");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
那个快乐地汇编着-std=c++14.
我遇到了这个,因为我有一个循环索引,std::vector并想要向后循环,所以我把它改为
for (std::size_t i = std::min(idx, v.size() - 1); i != std::size_t(-1); --i) { ... }
Run Code Online (Sandbox Code Playgroud)
现在,我意识到我可以使用std::vector::reverse_iterator,但我现在的真正问题是,我期待定义的行为是什么?
我正在学习 C++20 概念。有没有办法在 之前就地进行概念连接auto?例如,如果我有一个MutableGraph<G>概念和一个VertexListGraph<G>概念,我可以定义
template <typename G>
concept MutableVertexListGraph = MutableGraph<G> && VertexListGraph<G>;
Run Code Online (Sandbox Code Playgroud)
并做
MutableVertexListGraph auto g = ...;
Run Code Online (Sandbox Code Playgroud)
但是当我只是希望它对这两个概念进行建模时,命名这个概念是很烦人的。如果我能做到就好了
MutableGraph && VertexListGraph auto g = ...; // && not allowed here.
Run Code Online (Sandbox Code Playgroud)
甚至类似的东西
template <typename T, concept... Concepts> // <- "concept" not allowed here.
concept ModelsAll = (Concepts<T> && ...);
...
ModelsAll<MutableGraph, VertexListGraph> auto g = ...;
Run Code Online (Sandbox Code Playgroud)
我当然可以
MutableGraph auto g = ...;
requires { MutableGraph<decltype(g)>; };
Run Code Online (Sandbox Code Playgroud)
缺乏对称性,或者
auto g = ...;
requires { …Run Code Online (Sandbox Code Playgroud) 如果我声明我的类struct alignas(16) C { int x; };,x保证与 16 字节对齐,或者编译器可以将其填充到 \xe2\x80\x9cleft\xe2\x80\x9d 上吗?关于什么template <typename T, std::size_t Align> struct alignas(Align) Aligned : T { using T::T; };?的 会T与Aligned<T, N>对齐吗N?T这是创建始终对齐的类型的正确方法吗?
有很多类似的问题,但我找不到这个问题:给定
template <typename T>
struct S {
int f(int x) const { return x; }
};
Run Code Online (Sandbox Code Playgroud)
我希望能够f根据T. 显而易见的事情不起作用:
#include <type_traits>
template <typename T>
struct MyProperty { static constexpr auto value = std::is_same_v<T, float>; };
template <typename T>
struct S {
template <typename = std::enable_if_t<MyProperty<T>::value>>
int f(int x) const { return x; }
};
int main() {
S<int> s;
}
Run Code Online (Sandbox Code Playgroud)
我能想到的最接近的是一个假人typename U = T:
template <typename U = T, typename = std::enable_if_t<MyProperty<U>::value>>
int f(int x) …Run Code Online (Sandbox Code Playgroud) 如果我std::array<T, N>用大括号构造 a 并给它少于N项目,那么这些项目是否为零初始化?(或者它们是否保留默认初始化?)如果我给它零个项目(即= {}),那么我相信它会将所有元素零初始化。
我找不到这个简单问题的明确答案。由于std::array在像 一样使用时使用聚合初始化std::array<int, 2> x = { 1 };,因此导致聚合初始化规则的https://en.cppreference.com/w/cpp/language/aggregate_initialization 。在那里,我看到的关于这种情况的唯一提及是“如果指定了数组的大小并且它大于字符串文字中的字符数,则其余字符将被零初始化。” 但这是在“字符数组”部分中,所以看起来通常不是这样。另一方面,用作constexrpUB 检测器表明它们已归零: https: //godbolt.org/z/zE9xKvbrq
有关的:
我对调用约定的理解是,函数在调用者要求的地方(或者在传统的地方?)构造它们的结果。考虑到这一点,这让我感到惊讶:
#include <memory>
struct X; // Incomplete type.
// Placement-new a null unique_ptr in-place:
void constructAt(std::unique_ptr<X>* ptr) { new (&ptr) std::unique_ptr<X>{nullptr}; }
// Return a null unique_ptr:
std::unique_ptr<X> foo() { return std::unique_ptr<X>{nullptr}; }
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/rqb1fKq3x
虽然可以constructAt编译,但很高兴放置new一个 null unique_ptr<X>,foo()但无法编译,因为编译器想要实例化unique_ptr<X>::~unique_ptr()。我理解为什么它不能实例化该析构函数(因为就语言而言,它需要遵循nullptrd'tor 的非分支,然后删除内存 [/sf/ask/1996536531/ /为什么唯一的ptrtunique-ptr需要t的定义])。基本上没有完整的X, 的unique_ptr析构函数就会被 SFINAE 掉(对吗?)。但是为什么返回值的函数必须知道如何破坏该值呢?难道调用者不是必须破坏它的人吗?
显然,我的职责constructAt和foo职能在道德上并不等同。这种语言是迂腐的,还是有一些代码路径(例外?)必须foo()破坏该值?