对于移动启用的类,这两者之间有区别吗?
struct Foo {
typedef std::vector<std::string> Vectype;
Vectype m_vec;
//this or
void bar(Vectype&& vec)
{
m_vec = std::move(vec);
}
//that
void bar(Vectype vec)
{
m_vec = std::move(vec);
}
};
int main()
{
Vectype myvec{"alpha","beta","gamma"};
Foo fool;
fool.bar(std::move(myvec));
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,如果你使用左值,myvec你还需要引入const
Vectype&版本,Foo::bar()因为Vectype&&不会绑定.除此之外,在rvalue情况下,Foo::bar(Vectype)将使用移动构造函数构造向量或更好地将副本全部放在一起,看到vec是一个右值(是吗?).那么有没有令人信服的理由不通过值声明而不是左值和右值超载?(考虑到我需要在任何情况下将向量复制到成员变量.)
C++中的一个常见模式是将复制构造函数设为私有:
class A
{
public:
// ...
private:
A(const A&);
};
Run Code Online (Sandbox Code Playgroud)
但是下面的代码会编译(在C++ 11/14中):
A f();
auto a = f();
Run Code Online (Sandbox Code Playgroud)
该标准包含有关自动生成移动构造函数的信息.我既无法访问标准,也无法访问实际生成移动构造函数的编译器.我的问题是:我必须写
class A
{
public:
// ...
private:
A(const A&);
A(const A&&);
};
Run Code Online (Sandbox Code Playgroud)
防止移动(和运营商=类似)?
这样一个例子更容易解释,
class base {
//....
}
class derived1 : public base {
//...
}
Run Code Online (Sandbox Code Playgroud)
在我的库中,有一个基类指针.库的用户必须创建从base或derived1派生的类,并分配指向该类的指针.
如何检查从哪个类派生的用户定义类?
我正在查看std::optional<T>关于cppreference的API .我很好奇如何value_or工作.看那里,似乎有两个重载:
template< class U >
constexpr T value_or( U&& value ) const&;
template< class U >
T value_or( U&& value ) &&;
Run Code Online (Sandbox Code Playgroud)
什么是const&和&&尾随函数声明?声明函数const和声明函数之间有什么区别const&?
我最近在SE上发布了一个关于下面代码的问题,因为它产生了编译错误.当你实现移动构造函数或移动赋值运算符时,有人会回答这个问题,然后删除默认的复制构造函数.他们还建议我然后使用它std::move()来获得这样的东西:
Image src(200, 200);
Image cpy = std::move(src);
Run Code Online (Sandbox Code Playgroud)
现在这对我有意义,因为在这种情况下你想要使用移动赋值运算符或移动构造函数的事实必须明确.src在这个例子中是一个左值,没有任何东西可以告诉编译器,而不是你实际想要移动它的内容,cpy除非你明确表达std::move.但是,我对此代码有更多问题:
Image cpy = src + src
Run Code Online (Sandbox Code Playgroud)
我没有把副本放在operator +下面,但它是一个简单的类型的重载运算符:
Image operator + (const Image &img) const {
Image tmp(std::min(w, img.w), std::min(h, img.h));
for (int j = 0; j < tmp.h; ++j) {
for (int i = 0; i < tmp.w; ++i) {
// accumulate the result of the two images
}
}
return tmp;
}
Run Code Online (Sandbox Code Playgroud)
在这种特殊情况下,我假设操作符以形式返回临时变量,tmp并且当你到达时,将触发移动分配操作符cpy = src + …
假设我有std::vector V5个元素,
V.erase(V.begin() + 2) 删除第3个元素.
STL vector实现将向上移动第4和第5个元素,然后破坏第5个元素.
即在e中删除元素ivector并不保证调用第i个析构函数.因为std::list,事实并非如此.擦除ith元素调用ith元素的析构函数.
STL对这种行为有什么看法?
这是从我的系统的stl_vector.h获取的代码:
392 iterator erase(iterator __position) {
393 if (__position + 1 != end())
394 copy(__position + 1, _M_finish, __position);
395 --_M_finish;
396 destroy(_M_finish);
397 return __position;
Run Code Online (Sandbox Code Playgroud) AFAIK C++ atomics(<atomic>)系列提供3个好处:
我不确定第三个子弹,因此请看下面的例子.
#include <atomic>
std::atomic_bool a_flag = ATOMIC_VAR_INIT(false);
struct Data {
int x;
long long y;
char const* z;
} data;
void thread0()
{
// due to "release" the data will be written to memory
// exactly in the following order: x -> y -> z
data.x = 1;
data.y = 100;
data.z = "foo";
// there can be an arbitrary delay between the write
// to any of the members and it's …Run Code Online (Sandbox Code Playgroud) 我有一个问题,即创建函数指针编译错误重载函数结果对于g ++ 4.7和g ++ 4.8但不在克++ 4.4,G ++ 4.6或铛++ 3.2(以及可能VS2010).
谷歌搜索了一下是为了解问问题是用g ++还是我的代码,我还是无法决定.适用于函数指针转换的重载决策规则是否不同于适用于函数调用的规则?
这是一个稍微最小化的代码,用于演示此问题:
template < class T >
struct Dummy {
typedef T value_type;
value_type value;
};
template < class T >
typename T::value_type f (const T& x) {
return x.value;
}
template < class T >
T f (Dummy< T > const& x) {
return x.value + 1;
}
int main (int, char**) {
Dummy< int > d = { 1 };
// No ambiguity here
d.value = f(d);
// …Run Code Online (Sandbox Code Playgroud) 以下是三次尝试实现is_constexpr()根据理查德·史密斯的回答到是is_constexpr可能在C ++ 11?
版本1
template <typename T>
bool constexpr is_constexpr_impl_1(const T& x, decltype(int{(x, 0u)})) { return true; }
template <typename T>
bool constexpr is_constexpr_impl_1(const T&, ...) { return false; }
template <typename T>
bool constexpr is_constexpr_1(const T& x) { return is_constexpr_impl_1(x, 0); }
Run Code Online (Sandbox Code Playgroud)
版本2
template <typename T>
bool constexpr is_constexpr_impl_2(const T& f, decltype(int{(f(0), 0u)})) { return true; }
template <typename T>
bool constexpr is_constexpr_impl_2(const T&, ...) { return false; }
template <typename T> …Run Code Online (Sandbox Code Playgroud) 为什么这段代码不起作用?
std::shared_ptr<Event> e = ep->pop();
std::shared_ptr<TrackerEvent> t;
t = std::dynamic_pointer_cast<TrackerEvent>(e);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
/usr/include/c++/4.6/bits/shared_ptr.h:386: error: cannot dynamic_cast '(& __r)->std::shared_ptr<Event>::<anonymous>.std::__shared_ptr<_Tp, _Lp>::get [with _Tp = Event, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]()' (of type 'class Event*') to type 'class TrackerEvent*' (source type is not polymorphic)
Run Code Online (Sandbox Code Playgroud)
TrackerEvent继承自Event所以我猜问题是我不能朝这个方向投.但是ep->pop()可能会返回一个类型的对象Event或TrackerEvent.我希望,当我尝试将其转换为TrackerEvent并返回NULL我想知道我是否有一个Event或TrackerEvent...
我该怎么办?
c++ ×10
c++11 ×7
atomicity ×1
c++17 ×1
class ×1
constexpr ×1
dynamic-cast ×1
gcc ×1
overloading ×1
shared-ptr ×1
stl ×1