使用类模板参数推导我们可以写:
std::less Fn;
Run Code Online (Sandbox Code Playgroud)
但是,G ++ 8.2拒绝此代码:
#include <algorithm>
#include <vector>
#include <functional>
int main()
{
std::vector v= { 1, 3, 2, 7, 5, 4 };
std::sort(v.begin(),v.end(),std::greater());
}
Run Code Online (Sandbox Code Playgroud)
发出以下错误:
error: cannot deduce template arguments for 'greater' from ()
Run Code Online (Sandbox Code Playgroud)
Clang ++ 7.0和MSVC 15.8.0在没有警告的情况下编译它.哪个编译器是对的?
考虑头文件:
class T
{
private:
int const ID;
public:
explicit T(int const ID_) noexcept : ID(ID_) {}
int GetID() const noexcept { return ID; }
};
Run Code Online (Sandbox Code Playgroud)
或者,或者:
class T
{
private:
int const ID;
public:
explicit T(int const ID_) noexcept;
int GetID() const noexcept;
};
inline T::T(int const ID_) noexcept : ID(ID_) {}
inline int T::GetID() const noexcept { return ID; }
Run Code Online (Sandbox Code Playgroud)
在预模块世界中,这些标头可能会以文本形式包含在多个 TU 中,而不会违反 ODR。此外,由于涉及的成员函数相对较小,编译器可能会“内联”(在使用时避免函数调用)这些函数,甚至优化掉一些实例T
。
在最近关于 C++20 完成会议的报告中,我可以阅读以下声明:
我们澄清了
inline
模块接口中的含义:意图是未明确声明的函数体不是inline
模块 ABI 的一部分,即使这些函数体出现在模块接口中。为了让模块作者更好地控制他们的 …
c ++标准的最后一个草案引入了所谓的"自定义点对象"([customization.point.object]),它们被范围库广泛使用.
我似乎明白,他们提供一种方式来编写的定制版本begin
,swap
,data
等,这是由ADL标准库中找到.那是对的吗?
这与用户begin
在她自己的命名空间中为她的类型定义重载的先前实践有何不同?特别是,他们为什么反对?
GCC9已经实施std::is_constant_evaluated
.我玩了一点,我意识到这有点棘手.这是我的测试:
constexpr int Fn1()
{
if constexpr (std::is_constant_evaluated())
return 0;
else
return 1;
}
constexpr int Fn2()
{
if (std::is_constant_evaluated())
return 0;
else
return 1;
}
int main()
{
constexpr int test1 = Fn1(); // Evaluates to 0
int test2 = Fn1(); // Evaluates to 0
int const test3 = Fn1(); // Evaluates to 0
constexpr int test4 = Fn2(); // Evaluates to 0
int test5 = Fn2(); // Evaluates to 1
int const test6 = Fn2(); // …
Run Code Online (Sandbox Code Playgroud) 在下面的示例中,函数自变量用于测试require表达式是否充分利用了它们。require表达式不带参数;它直接使用函数作用域中的变量:
#include <cstddef>
#include <vector>
template<typename T>
void Resize(T &v, std::size_t const n)
{
if constexpr (requires { v.resize(n); })
v.resize(n);
}
template<typename T>
void Eziser(T &v, std::size_t const n)
{
if constexpr (requires { v.eziser(n); })
v.eziser(n);
}
int main()
{
std::vector<int> v;
Resize(v, 10u);
Eziser(v, 10u);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码使用Clang概念分支进行编译。但是,GCC10仅接受对的呼叫Resize
。GCC9 ICE。Clang正确接受吗?
G++ 和 Clang++ 同意以下代码段不是有效的 C++:
template<int dim, int rank>
struct Tensor {};
template<int dim>
double InnerProduct(Tensor<dim, 1> const &, Tensor<dim, 1> const &)
{ return 0.0; }
template<int dim>
double DoubleInnerProduct(Tensor<dim, 2> const &, Tensor<dim, 2> const &)
{ return 0.0; }
template<int dim, int rank>
class Field
{
private:
static double Dot(Tensor<dim, rank> const &u, Tensor<dim, rank> const &v) requires (rank == 1)
{ return InnerProduct(u, v); }
static double Dot(Tensor<dim, rank> const &u, Tensor<dim, rank> const &v) requires …
Run Code Online (Sandbox Code Playgroud) c++ language-lawyer explicit-instantiation c++-concepts c++20
可能这个全局函数遭受静态初始化惨败吗?
template <typename TFn>
void ParallelFor(int iIni,int iFin,TFn Fn)
{
static const unsigned int NThread= std::thread::hardware_concurrency();
// ...
}
Run Code Online (Sandbox Code Playgroud) 有可能让这个代码按照我的意愿工作吗?即允许概念访问私有成员函数?
template <typename T>
concept bool Writeable()
{ return requires (T x,std::ostream os) { { x.Write(os) } -> void }; }
template <Writeable T>
void Write(std::ostream &os,const T &x) { x.Write(os); }
class TT
{
private:
void Write(std::ostream &os) const { os << "foo"; }
//friend concept bool Writeable<TT>();
friend void ::Write<TT>(std::ostream &,const TT &);
};
Run Code Online (Sandbox Code Playgroud)
谢谢
我有一个可以简化为基本的并行代码:
#include <algorithm>
#include <vector>
struct TKeyObjPtr;
class TObj
{
public:
virtual void Calculate(TKeyObjPtr const &) = 0;
};
struct TKeyObjPtr
{
int Key;
TObj *ObjPtr;
};
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
#pragma omp parallel for
for (auto It1= KeyObjPtrVec.begin(); It1!=KeyObjPtrVec.end(); ++It1)
for (auto It2= It1+1; It2!=KeyObjPtrVec.end() && It2->Key==It1->Key; ++It2)
It1->ObjPtr->Calculate(*It2);
}
Run Code Online (Sandbox Code Playgroud)
我想通过使用c ++ 17并行算法来实现代码的现代化.不幸的是,我在重写这么简单的代码时遇到了麻烦.
一个选项将使用boost::counting_iterator
:
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
std::for_each(std::execution::par_unseq,
boost::counting_iterator<std::size_t>(0u),
boost::counting_iterator<std::size_t>(KeyObjPtrVec.size()),
[&KeyObjPtrVec](auto i)
{
for (auto j= i+1; j<KeyObjPtrVec.size() && KeyObjPtrVec[j].Key==KeyObjPtrVec[i].Key; ++j)
KeyObjPtrVec[i].ObjPtr->Calculate(KeyObjPtrVec[j]); …
Run Code Online (Sandbox Code Playgroud) 在为该问题准备补充信息时,我注意到,与“传统”实现相比,非常简单的算法的“范围化”实现在结果汇编中(在我看来)导致了重要的差异。
我对测试进行了扩展,得到以下结果(GCC 9.1 -O3):
案例1.简单的for循环(https://godbolt.org/z/rAVaT2)
#include <vector>
void foo(std::vector<double> &u, std::vector<double> const &v)
{
for (std::size_t i = 0u; i < u.size(); ++i)
u[i] += v[i];
}
Run Code Online (Sandbox Code Playgroud) mov rdx, QWORD PTR [rdi]
mov rdi, QWORD PTR [rdi+8]
sub rdi, rdx
sar rdi, 3
je .L1
mov rcx, QWORD PTR [rsi]
lea rax, [rcx+15]
sub rax, rdx
cmp rax, 30
jbe .L7
lea rax, [rdi-1]
cmp rax, 1
jbe .L7
mov rsi, rdi
xor eax, eax
shr …
Run Code Online (Sandbox Code Playgroud) c++ ×10
c++20 ×5
c++17 ×4
c++-concepts ×3
c++-modules ×1
c++11 ×1
constexpr ×1
friend ×1
if-constexpr ×1
iterator ×1
range-v3 ×1
static ×1
templates ×1