移动操作应该是noexcept;首先是直观和合理的语义。第二个参数是运行时性能。来自核心指南C.66,“使移动操作 noexcept”:
投掷动作违反了大多数人的合理假设。标准库和语言设施将更有效地使用非投掷动作。
本指南性能部分的典型示例是std::vector::push_back朋友需要增加缓冲区的情况。标准在这里需要一个强大的异常保证,如果是这样,这只能将元素移动构造到新缓冲区中noexcept- 否则,必须复制它。我明白了,差异在基准测试中是可见的。
然而,除此之外,我很难找到noexcept移动语义对性能产生积极影响的真实证据。浏览标准库 ( libcxx+ grep),我们看到它std::move_if_noexcept存在,但它几乎没有在库本身中使用。同样,std::is_noexcept_swappable仅用于充实条件noexcept限定符。这与现有声明不符,例如 Andrist 和 Sehr 的“C++ High Performance”中的声明(第二版,第 153 页):
所有算法都在移动元素时使用
std::swap()andstd::move(),但前提是移动构造函数和移动赋值标记为 noexcept。因此,在使用算法时为重物实现这些很重要。如果它们不可用且无异常,则将复制元素。
把我的问题分成几部分:
std::vector::push_back输入std::is_nothrow_move_constructible类型时运行得更快?noexcept指南时,编译器何时能够可靠地生成运行时效率更高的代码?我知道第三个可能有点模糊。但是如果有人能想出一个简单的例子,那就太好了。
我读的文章周的老大师之一typename,#35。最后,您可以找到以下代码段:
Run Code Online (Sandbox Code Playgroud)#include <iostream> using std::cout; using std::endl; struct Rose {}; struct A { typedef Rose rose; }; template<class T> struct B : T { typedef typename T::rose foo; }; template<class T> void smell( T ) { cout << "awful" << endl; } void smell( Rose ) { cout << "sweet" << endl; } int main() { smell( A::rose() ); smell( B<A>::foo() ); }
我不明白 我的第一个猜测是,第二次smell调用导致模板smell被实例化,原因是您容易忽略了一些东西(笑话应该是什么,否则?!)。但是这两个调用都导致打印出“甜”字。毕竟这不是意料之中的吗?在中typedef Rose rose;,Rose不是依赖名称,所以很好。在typedef …
I am currently in the process of updating my language knowledge (to C++17). I was trying to get this code to compile using gcc and couldn't figure it out so I tried MSVC and clang and both seem okay with this code -- is there anything wrong with this bit of code?
gcc seems to be complaining about instantiating a tuple<> with no template parameters which is odd:
prog.cc: In instantiation of 'C::C(U&& ...) [with U = {const A&, const …
我从这里获得的问题的依据是: 无法从lambda函数推断出模板参数std :: function 。此线程中的问题是:为什么此代码无法将lambda传递给函数:
#include <iostream>
#include <functional>
template <typename T>
void call(std::function<void(T)> f, T v)
{
f(v);
}
int main(int argc, char const *argv[])
{
auto foo = [](int i) {
std::cout << i << std::endl;
};
call(foo, 1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该线程的答案是,因为lambda不是a std::function。但是为什么这段代码会编译:
#include <iostream>
#include <functional>
template <typename T>
void call(std::function<void(T)> f, T v)
{
f(v);
}
int main(int argc, char const *argv[])
{
auto foo = [](int i) {
std::cout << i << std::endl; …Run Code Online (Sandbox Code Playgroud) In this recent question, we saw that it's not allowed to reinterpret_cast some custom class type instance to itself; struct A{}; reinterpret_cast<A>(A{}); is invalid (it works only through references or pointers). Which seems to make sense, because of the lack of real-world scenarios where such identity conversion is necessary.
Checking the corresponding standard clause, we have in [expr.reinterpret.cast] (emphasis mine):
1 [...] Conversions that can be performed explicitly using
reinterpret_castare listed below. No other conversion can be performed …
为什么动态转换仅适用于指针和引用?说我有这样的东西
struct foo
{
virtual void test(){}
};
struct bar : public foo
{
};
Run Code Online (Sandbox Code Playgroud)
为什么这样的东西不起作用
foo* f = new bar();
bar& b = dynamic_cast<bar>(*f); //Fail must be either pointer or reference
Run Code Online (Sandbox Code Playgroud)
现在假设bar它的父级 foo 确实有一个转换构造函数。我的问题是为什么动态转换只接受指针和引用而不是像这样的简单对象static_cast?
我有一个已经排序的向量,称为vec,还有一个目标变量。目标是返回最接近目标的向量元素。
我试图将C ++ 11 lambda函数与[=]一起使用以捕获外部变量
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec{1,2,3,4,5};
double target = 3.14159;
int res = min(vec.begin(), vec.end(), [=](int v1, int v2) -> bool {
return abs(v1-target) < abs(v2-target);
});
cout << res << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望得到res = 3,但是会返回错误:
error: cannot convert 'const __gnu_cxx::__normal_iterator<int*, std::vector<int> >' to 'int' in initialization
Run Code Online (Sandbox Code Playgroud) make_shared的CppReference页面说(与make_unique相同)
可能引发std :: bad_alloc或T的构造函数引发的任何异常。如果引发异常,则这些函数无效。
这意味着在失败的情况下可以引发std :: bad_alloc接收。“函数无效”暗含意味着它无法返回nullptr。如果是这种情况,为什么不总是将make_shared / make_unique始终写入try catch块中是一种惯例?
使用make_shared的正确方法是什么?在尝试捕获块内?或检查nullptr?
我正在尝试获得eval在r7rs鸡蛋库中工作的基本知识。以下顶级(不是库)程序按我的预期工作,运行时csi -R r7rs:
(import (scheme base)
(scheme eval))
(eval '42 (scheme-report-environment 5))
Run Code Online (Sandbox Code Playgroud)
这也适用于(null-environment 5)(但不适用于(environment '(scheme base) ...)变体)。但是,在库中:
(define-library (test-eval)
(import
(scheme base)
(scheme eval))
(export
my-eval)
(begin
(define (my-eval)
(eval '42 (scheme-report-environment 5)))))
Run Code Online (Sandbox Code Playgroud)
我得到
Error: module unresolved: test-eval
....
<syntax> [my-eval] (scheme-report-environment 5)
<syntax> (##core#begin)
<syntax> (##core#undefined) <--
Run Code Online (Sandbox Code Playgroud)
可能是什么问题呢?Wiki 中的R7RS 环境似乎存在一些问题,但我不确定这是否与此处相关。
用鸡 5.2.0 版(自制程序包)测试,两者csi和csc.
我从C ++ 17了解到,借助推论指南,可以从例如初始化中推导std :: vector的模板参数:
std::vector vec = { function_that_calculate_and_return_a_specifically_templated_type() }
Run Code Online (Sandbox Code Playgroud)
但是,我现在不想编译和运行代码的机器上没有C ++ 17的支持。
C ++ 11是否有任何可能的解决方法?如果存在更多解决方案,那么最好的解决方案就是保持代码的可读性。
目前,我唯一的想法是跟踪代码中的各种情况(幸运的是,它们不应太多)并进行一些显式的typedef / using。
任何建议都非常欢迎