unique_ptr<T>不允许复制构造,而是支持移动语义.然而,我可以unique_ptr<T>从函数返回一个并将返回的值赋给变量.
#include <iostream>
#include <memory>
using namespace std;
unique_ptr<int> foo()
{
unique_ptr<int> p( new int(10) );
return p; // 1
//return move( p ); // 2
}
int main()
{
unique_ptr<int> p = foo();
cout << *p << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码按预期编译和工作.那么该行如何1不调用复制构造函数并导致编译器错误呢?如果我必须使用line 2而不是它有意义(使用line 2也可以,但我们不需要这样做).
我知道C++ 0x允许此异常,unique_ptr因为返回值是一个临时对象,一旦函数退出就会被销毁,从而保证返回指针的唯一性.我很好奇这是如何实现的,它是在编译器中特殊的,还是在语言规范中有一些其他条款可以利用?
我想知道如何正确检查是否std::function为空.考虑这个例子:
class Test {
std::function<void(int a)> eventFunc;
void registerEvent(std::function<void(int a)> e) {
eventFunc = e;
}
void doSomething() {
...
eventFunc(42);
}
};
Run Code Online (Sandbox Code Playgroud)
这段代码在MSVC中编译得很好,但如果我在doSomething()没有初始化的情况下调用eventFunc代码,那么显然会崩溃.这是预期的,但我想知道它的价值是eventFunc多少?调试器说'empty'.所以我使用简单的if语句修复了它:
void doSomething() {
...
if (eventFunc) {
eventFunc(42);
}
}
Run Code Online (Sandbox Code Playgroud)
这有效,但我仍然想知道非初始化的价值是std::function多少?我想写,if (eventFunc != nullptr)但std::function(显然)不是指针.
为什么纯净如果有效?它背后的魔力是什么?而且,这是检查它的正确方法吗?
为unique_ptr保证存储nullptr移动之后?
std::unique_ptr<int> p1{new int{23}};
std::unique_ptr<int> p2{std::move(p1)};
assert(!p1); // is this always true?
Run Code Online (Sandbox Code Playgroud) 我在Mac OS X(10.8.2)下使用C++工作,最近我想出了使用C++ 11功能的需求,这些功能可以通过使用libc ++ stdlib的clang ++编译器获得.但是,我还需要使用一些针对libstdc ++编译和链接的遗留库(来自MacPorts).
在这样做时,我得到了链接错误,因为遗留库的标题使用,例如std::string,需要解决std::__1::basic_string(即,libc ++实现std::string)而不是std::basic_string实现.
有没有办法在开发中混合两个库(例如,通过使用一些预处理器标志?)
我有一系列工厂回归unique_ptr<Base>.引擎盖下,虽然,他们所提供的指针各种衍生类型,即unique_ptr<Derived>,unique_ptr<DerivedA>,unique_ptr<DerivedB>等
鉴于DerivedA : Derived并且Derived : Base我们有:
unique_ptr<Base> DerivedAFactory() {
return unique_ptr<Base>(new DerivedA);
}
Run Code Online (Sandbox Code Playgroud)
我需要做的是将指针从返回"转换" unique_ptr<Base>到某个派生级别(不一定是原始的内部级别).用伪代码说明:
unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());
Run Code Online (Sandbox Code Playgroud)
我正在考虑通过从中释放对象unique_ptr,然后使用一个转换原始指针的函数并将其重新分配给另一个unique_ptr所需的风格(release在调用之前由调用者显式完成)来实现这一点:
unique_ptr<Derived> CastToDerived(Base* obj) {
return unique_ptr<Derived>(static_cast<Derived*>(obj));
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,还是/会有什么时髦吗?
PS.还有一个复杂的问题是,有些工厂驻留在运行时动态加载的DLL中,这意味着我需要确保生成的对象在创建它们的同一个上下文(堆空间)中被销毁.所有权的转移(通常发生在另一个上下文中)必须从原始上下文中提供删除.但除了必须与指针一起提供/转换删除器之外,铸造问题应该是相同的.
std::vector<char> p = {"abc", "def"};
Run Code Online (Sandbox Code Playgroud)
"abc"并且"def"不是char,为什么编译器没有给我一个关于这种类型不匹配的错误?
我正在阅读"Effective Modern C++".在与std::unique_ptr它相关的项目中声明如果自定义删除器是无状态对象,则不会出现大小费用,但如果它是函数指针或std::function大小费用发生.你能解释一下原因吗?
假设我们有以下代码:
auto deleter_ = [](int *p) { doSth(p); delete p; };
std::unique_ptr<int, decltype(deleter_)> up(new int, deleter_);
Run Code Online (Sandbox Code Playgroud)
根据我的理解,unique_ptr应该有一个类型的对象decltype(deleter_)并分配deleter_给该内部对象.但显然这不是正在发生的事情.你能用最小的代码示例来解释这背后的机制吗?
浏览Linux内核源代码时,我发现了一段代码,其中括号括起来的语句块被视为表达式a laisp(或ML),即表达式,其值是最后一个语句的值.
例如:
int a = ({
int i;
int t = 1;
for (i = 2; i<5; i++) {
t*=i;
}
t;
});
Run Code Online (Sandbox Code Playgroud)
我一直在研究ANSI C语法,试图弄清楚这段代码如何适合解析树,但我还没有成功.
那么,有没有人知道这种行为是由标准规定还是只是GCC的特殊性?
更新:我已尝试使用标志-pedantic,编译器现在给我一个警告:
warning: ISO C forbids braced-groups within expressions
Run Code Online (Sandbox Code Playgroud) 考虑功能:
template<typename T>
void printme(T&& t) {
for (auto i : t)
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
或任何其他期望一个参数具有begin()/ end()启用类型的函数.
以下为什么违法?
printme({'a', 'b', 'c'});
当所有这些都合法时:
printme(std::vector<char>({'a', 'b', 'c'}));
printme(std::string("abc"));
printme(std::array<char, 3> {'a', 'b', 'c'});
Run Code Online (Sandbox Code Playgroud)
我们甚至可以这样写:
const auto il = {'a', 'b', 'c'};
printme(il);
Run Code Online (Sandbox Code Playgroud)
要么
printme<std::initializer_list<char>>({'a', 'b', 'c'});
Run Code Online (Sandbox Code Playgroud) 我正在进入C++ 11线程并遇到了问题.
我想将一个线程变量声明为全局并稍后启动它.
然而,我见过的所有例子似乎都是立即启动线程的
thread t(doSomething);
Run Code Online (Sandbox Code Playgroud)
我想要的是
thread t;
Run Code Online (Sandbox Code Playgroud)
并稍后启动该帖子.
我试过的是
if(!isThreadRunning)
{
thread t(readTable);
}
Run Code Online (Sandbox Code Playgroud)
但现在是块范围.所以我想声明t然后稍后启动线程,以便其他函数可以访问t.
谢谢你的帮助.
c++ ×9
c++11 ×9
unique-ptr ×4
c ×1
c++14 ×1
clang ×1
expression ×1
gcc ×1
libc++ ×1
libstdc++ ×1
standards ×1
std-function ×1
templates ×1