通过string_view使用C ++ 17,我们得到了一种便宜的方法,该方法将std::string和传递char*给不占用字符串所有权并避免制作临时副本的函数。通过使用std::string按值传递,std::move我们可以为r值和l值引用显式快速地传递字符串所有权。
我的问题是:const std::string&在新的C ++标准中用作任何函数参数有什么好处?
想象一下以下声明:
void foo(){
const std::array<int, 80000> arr = {/* a lot of different values*/};
//do stuff
}
Run Code Online (Sandbox Code Playgroud)
第二个:
void foo(){
static const std::array<int, 80000> arr = {/* a lot of different values*/};
//do stuff
}
Run Code Online (Sandbox Code Playgroud)
如果有的话,这两者之间可能存在哪些性能差异?这些解决方案是否有任何危险?
我正在为将来的库编写一些通用代码。我在模板函数中遇到以下问题。考虑下面的代码:
template<class F>
auto foo(F &&f) {
auto result = std::forward<F>(f)(/*some args*/);
//do some generic stuff
return result;
}
Run Code Online (Sandbox Code Playgroud)
除非我将返回的函数传递给它,否则它将正常工作void:
foo([](){});
Run Code Online (Sandbox Code Playgroud)
现在,当然,我现在可以使用一些std::enable_if魔术来检查返回类型,并对返回的函数执行专门化的操作void,如下所示:
template<class F, class = /*enable if stuff*/>
void foo(F &&f) {
std::forward<F>(f)(/*some args*/);
//do some generic stuff
}
Run Code Online (Sandbox Code Playgroud)
但这将完全复制实际上逻辑上等效的功能的代码。能否以一种优雅的方式,以通用的方式轻松地对- void返回和非void返回功能同时进行?
编辑:f()我想做的功能和通用的东西之间有数据依赖关系,所以我不考虑这样的代码:
template<class F>
auto foo(F &&f) {
//do some generic stuff
return std::forward<F>(f)(/*some args*/);
}
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
#include <cstdint>
#include <algorithm>
std::uintptr_t minPointer(void *first, void *second) {
const auto pair = std::minmax(
reinterpret_cast<std::uintptr_t>(first),
reinterpret_cast<std::uintptr_t>(second)
);
return pair.first;
}
Run Code Online (Sandbox Code Playgroud)
并且所产生的组件通过与-O3 GCC8上
https://godbolt.org/z/qWJuV_为minPointer:
minPointer(void*, void*):
mov rax, QWORD PTR [rsp-8]
ret
Run Code Online (Sandbox Code Playgroud)
这显然不符合代码创建者的意图.这个代码是导致某些UB还是GCC(8)错误?
以下面的代码为例
#include <algorithm>
namespace baz {
template<class T>
void sort(T&&){}
}
namespace boot {
const auto sort = [](auto &&){};
}
void foo (){
using namespace std;
using namespace baz;
sort(1);
}
void bar(){
using namespace std;
using namespace boot;
sort(1);
}
Run Code Online (Sandbox Code Playgroud)
我希望既然已经foo编译,那么也bar将进行编译。令我惊讶的是,foo编译正确,并且bar对sort函数的歧义调用存在问题。我在这里做非法的事情,还是这是编译器应该表现的正确方式?如果是这样,为什么会如此不同。虽然我可以将通用lambda视为通用功能的语法糖。
最近,我编写了一个模板函数来解决一些代码重复。看起来像这样:
template<class T, class R, class... Args>
R call_or_throw(const std::weak_ptr<T>& ptr, const std::string& error, R (T::*fun)(Args...), Args... args) {
if (auto sp = ptr.lock())
{
return std::invoke(fun, *sp, args...);
}
else
{
throw std::runtime_error(error.c_str());
}
}
int main() {
auto a = std::make_shared<A>();
call_or_throw(std::weak_ptr<A>(a), "err", &A::foo, 1);
}
Run Code Online (Sandbox Code Playgroud)
这段代码非常适合class A如下所示:
class A {
public:
void foo(int x) {
}
};
Run Code Online (Sandbox Code Playgroud)
但无法像这样编译:
class A {
public:
void foo(const int& x) {
}
};
Run Code Online (Sandbox Code Playgroud)
为什么会这样(为什么我要说为什么它无法推断类型)以及如何(如果可能的话)使此代码与引用一起使用? 现场例子
因为你可能(不)知道使用std::minmax自动和临时参数可能是危险的.以下代码例如是UB,因为std::minmax返回引用对,而不是值:
auto fun(){
auto res = std::minmax(3, 4);
return res.first;
}
Run Code Online (Sandbox Code Playgroud)
我想问一下是否有可能使std::minmax功能安全或至少更安全,没有任何开销?我提出了这样的解决方案,但我不完全确定它是否等同于当前,minmax因为生成的程序集对于类似stl的实现和我的不同.所以,问题是:什么是我实现的可能的问题/缺点,minmax相对于std样之一:
//below is std-like minmax
template< class T >
constexpr std::pair<const T&,const T&> std_minmax( const T& a, const T& b ){
return (b < a) ? std::pair<const T&, const T&>(b, a)
: std::pair<const T&, const T&>(a, b);
}
//below is my minmax implementation
template< class T >
constexpr std::pair<T, T> my_minmax( T&& a, T&& b ){
return …Run Code Online (Sandbox Code Playgroud) 如何避免在 C++ 中使用链式选项嵌套 if 语句?
例如,如果类型 A 包含 anstd::optional<B> b和类型 B an std::optional<C> c,我希望能够编写如下内容:
const auto v = if_exists(if_exists(a->b)->c);
Run Code Online (Sandbox Code Playgroud)
如果 b 或 c 是空可选项,则 v 将从 c 或空可选项中获取值。
我认为这样嵌套 ifs 会更好:
if (a->b) {
const auto b = *(a->b);
if (b->c) {
const auto c = *(b->c);
}
}
Run Code Online (Sandbox Code Playgroud)
以下问题似乎朝这个方向发展,但我不确定如何将其调整到我的用例中:Haskell style "Maybe" type & *chaining* in C++11
在帮助解决模板模板参数中太多模板参数中出现的问题时,我脑子里出现了一个问题:在这种情况下,哪个编译器对编译是正确的:
template <template <typename, typename> class Op>
class Function
{
};
template <typename A, typename B, bool is_f = std::is_floating_point<A>::value || std::is_floating_point<B>::value > struct Operator;
template <typename A, typename B>
struct Operator<A, B, false>
{};
template <typename A, typename B>
struct Operator<A, B, true>
{};
using FunctionOperator = Function<Operator>;
int main(int argc, char * argv[]){
std::cout << "hi!\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC 7+编译它没有错误.Clang 6及更高版本给出错误,表明Operator模板作为模板参数传递时出现问题:
tmp.cpp:19:35: error: template argument has different template parameters than its …Run Code Online (Sandbox Code Playgroud) 想象一下运行以下简单代码的 N 个线程:
int res = num.fetch_add(1, std::memory_order_relaxed);
Run Code Online (Sandbox Code Playgroud)
在哪里num:
std::atomic<int> num = 0;
Run Code Online (Sandbox Code Playgroud)
假设res对于每个运行代码的线程来说是否完全安全,或者对于某些线程来说它可能是相同的?