让我们假设我想写一个结构体,它有一个成员 constexpr std::array ,它包含前 N 个 fibs,其中 N 是一个模板参数。
类似这样的东西,但 vals 在编译时可用:
template <int N>
struct first_n_fibs {
static_assert(N>0);
static const std::array<int, N> vals;
static std::array<int, N> init_fibs(){
std::array<int,N> result;
if (N==1) {
return std::array<int,N>{1};
} else {
result[0]=1;
result[1]=1;
for(int i =2; i<N;++i) {
result[i]=result[i-2]+result[i-1];
}
}
return result;
}
};
template<int N>
const std::array<int, N> first_n_fibs<N>::vals=init_fibs();
int main(){
std::cout << first_n_fibs<2>::vals.back() << std::endl;
std::cout << first_n_fibs<5>::vals.back() << std::endl;
std::cout << first_n_fibs<6>::vals.back() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我怀疑没有解决方法,因为 std::array 构造函数不是 constexpr,所以如果有人知道任何涉及 …
我有以下代码实现以下类型特征:
std::vector std::vector整数它有效,但它非常冗长.
是否有更短/更好的方式来使用概念写这个?
我知道我可以从range-v3或其他类似的库中窃取概念,但我们假设我想自己实现它.
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
template <class T>
struct is_vector {
static constexpr bool value = false;
};
template <class T, class A>
struct is_vector<std::vector<T, A> > {
static constexpr bool value = true;
};
template <class T>
struct is_vector_of_int {
static constexpr bool value = false;
};
template <class A>
struct is_vector_of_int<std::vector<int, A> > {
static constexpr bool value = true;
};
// TODO add _v bool …Run Code Online (Sandbox Code Playgroud) 我发现许多嵌套的std :: conditional_t难以阅读,所以我选择了一个不同的模式(在自动返回类型的函数上调用decltype):
template<bool is_signed, std::size_t has_sizeof>
auto find_int_type(){
static_assert(sizeof(int)==4);
if constexpr(is_signed){
if constexpr(has_sizeof==4){
return int{};
} else if constexpr (has_sizeof==8){
return std::int64_t{};
} else {
return;
}
} else {
if constexpr(has_sizeof==4){
return (unsigned int){};
}
else if constexpr (has_sizeof==8){
return std::uint64_t{};
} else {
return;
}
}
}
static_assert(std::is_same_v<int, decltype(find_int_type<true, 4>())>);
static_assert(std::is_same_v<unsigned int, decltype(find_int_type<false, 4>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 3>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 5>())>);
static_assert(std::is_same_v<std::int64_t, decltype(find_int_type<true, 8>())>);
static_assert(std::is_same_v<std::uint64_t, decltype(find_int_type<false, 8>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 9>())>);
Run Code Online (Sandbox Code Playgroud)
我的问题是:
有没有更好的办法?
编译这种方式比std :: conditional_t慢(假设我需要实例化的类型比我刚才使用内置类型的示例更广泛).
PS这是一个玩具示例,IRCode我会处理一些更复杂的类型.
我有一个简单的程序:
int main()
{
return 2*7;
}
Run Code Online (Sandbox Code Playgroud)
GCC和clang优化启动时会生成2指令二进制,但icc会产生奇怪的输出.
push rbp #2.1
mov rbp, rsp #2.1
and rsp, -128 #2.1
sub rsp, 128 #2.1
xor esi, esi #2.1
mov edi, 3 #2.1
call __intel_new_feature_proc_init #2.1
stmxcsr DWORD PTR [rsp] #2.1
mov eax, 14 #3.12
or DWORD PTR [rsp], 32832 #2.1
ldmxcsr DWORD PTR [rsp] #2.1
mov rsp, rbp #3.12
pop rbp #3.12
ret
Run Code Online (Sandbox Code Playgroud) 我在boost源中找到了这一行:
const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
Run Code Online (Sandbox Code Playgroud)
我想知道在这里使用MACRO的目的是什么?
所有这一切都是为了增加ULL所提供的常数.
我认为它可能会被用来使人们更难以打字UL而不是打字ULL,但我想知道是否有任何其他理由使用它.
我正在考虑通过使用uint32_t和bool [4]的并集对返回4个bool的函数进行微优化,然后执行popcnt指令以查看bool数组中有多少个元素是正确的。
But I do not know if the standard guarantees that bool is represented as number with only 1 bit set when true and 0 bits set when it is false.
If the answer is no then I have a follow up question: if it is not required is it required that representation is constant, e.g. if I have a test that checks that true bool casted to uint_8t is 1(and 0 for false) does that this means that …
C++20 模式下的 MSVC 16.6 删除了 C++20 标准中删除的 result_of。我完全赞成做道德上正确的事情,但是我使用的许多 3rd 方库(示例)都失败了。
有时 MSVC 允许用户定义定义,以便仍启用已删除的功能。是否可以选择为 result_of 执行此操作?我已经尝试过 _HAS_FEATURES_REMOVED_IN_CXX20 并且它似乎有效,但是宏以 _ 开头的事实让我感到害怕,这表明它可能是内部 MSVC 机制,而不是用户应该设置的内容。
std::erase(_if)是对 C++20 的一个很好的补充(终于我可以忘记令人讨厌的擦除删除习惯用法),但有一点很奇怪:从某种意义上说,它不是一种通用算法,它只适用于 std:: 容器,例如它可以不对升压向量进行操作。
#include<string>
#include<vector>
#include<boost/container/vector.hpp>
int main() {
std::string str = " Hello World !";
std::erase(str, ' '); // :)
boost::container::vector<int> vi{1,2};
std::erase(vi, 2); // :(
}
Run Code Online (Sandbox Code Playgroud)
我最好的猜测是,该算法早在标准中投票概念之前就已经处于实验状态,因此需要进行大量工作来重新设计它,或者担心无法正确指定它的概念(即它会在某些情况下无法正确工作)具有时髦语义的用户定义类型)。
所以:我的问题是为什么这不是具有某些概念(或enable_if)要求/调度(例如地图/集)的通用算法?
我正在将一些代码从 MSVC(没有 permissive-)移植到 linux,我了解到如果在类的初始化列表中调用模板基类的构造函数,则必须指定所有模板参数,否则会出现错误。似乎有点多余,因为如果您在重新输入模板参数时犯了一个错误,那就是一个硬错误:
错误:类型 'Base<int, true>' 不是 'Derived' 的直接或虚拟基数
完整代码在这里:
template <typename T, bool has_x>
struct Base
{
Base(T t): t_(t){
}
T t_=0;
};
template <typename T>
class Derived : public Base<T, false>
{
public:
// : Base<T, true> is hard error
Derived(const T& t) : Base<T, false>(t) {}
};
int main()
{
Derived d(47);
}
Run Code Online (Sandbox Code Playgroud)
这是否有充分的理由,或者只是标准化过程从未花时间处理这个用例的特殊情况?
运行此代码时,线程清理程序会抱怨数据竞争。为什么?
#include <iostream>
#include <ranges>
#include <thread>
#include <vector>
int main(){
std::vector v{11,22,33,44,55,66};
auto view = v | std::ranges::views::filter([](const auto x){
return x>47;
});
std::jthread jt1([&]{
int sum =0;
for (const auto& val: view) {sum+=val;}
});
std::jthread jt2([&]{
int sum =0;
for (const auto& val: view) {sum+=val;}
});
}
Run Code Online (Sandbox Code Playgroud)
注意:我知道这个答案,我最近在看一个演讲中学到了它,但我发现它非常令人惊讶并且没有与此相关的现有问题,所以我想分享它。如果没有人有兴趣回答,我会自己回答。
c++ ×10
c++20 ×4
c++-concepts ×2
type-traits ×2
assembly ×1
boolean ×1
constexpr ×1
deprecated ×1
icc ×1
if-constexpr ×1
inheritance ×1
macros ×1
range-v3 ×1
stdarray ×1
stl ×1
templates ×1
visual-c++ ×1
x86 ×1