小编Alw*_*ing的帖子

std :: shared_ptr:reset()与赋值

这是一个基本问题,但我没有找到关于它的先前帖子.以下问题的标题听起来可能与我的问题相同,但问题本身与标题不匹配:使用shared_ptr.reset还是operator =?

我对reset()成员函数的目的感到困惑std::shared_ptr:除了赋值运算符之外,它还有什么作用呢?

具体来说,给定定义:

auto p = std::make_shared<int>(1);
Run Code Online (Sandbox Code Playgroud)
  1. 以下两行是否相同:

    p = std::make_shared<int>(5);
    p.reset(new int(5));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这些怎么样:

    p = nullptr;
    p.reset();
    
    Run Code Online (Sandbox Code Playgroud)

如果两条线在两种情况下都相同,那么目的是reset()什么?


编辑:让我重新说一下这个问题,以便更好地强调它的观点.问题是:是否有一种情况reset()可以让我们在没有它的情况下实现一些不容易实现的事情?

c++ shared-ptr c++11

40
推荐指数
2
解决办法
2万
查看次数

简洁可以节省哪些错误?

"C++ Primer"(第5版)建议在第149页上,简短的代码比较长的替代方案更不容易出错.它将以下代码行作为示例:

cout << *iter++ << endl;
Run Code Online (Sandbox Code Playgroud)

它声称上述行比其他行更不容易出错:

cout << *iter << endl;
++iter;
Run Code Online (Sandbox Code Playgroud)

对我来说,即使含义*iter++很明确,这个表达式仍然需要非零的心理努力来解析,因此第二个版本更具可读性.所以,我想理解:第二个版本更容易出错?

c++

25
推荐指数
3
解决办法
1546
查看次数

为什么抛出表达?

以下文章讨论了throw表达式的类型:在C++中,如果throw是一个表达式,它的类型是什么?.我想澄清一个更基本的问题:为什么应该throw是一个表达式而不是一个(非表达式)语句就像return在第一个位置一样?我的意思是,有人想写点什么auto x = throw std::runtime_error("Error message")吗?

c++

17
推荐指数
1
解决办法
644
查看次数

为什么继承的构造函数不能继承默认参数?

C++ Primer(第5版)第629页指出:

  • 如果基类构造函数具有默认参数,则不会继承这些参数.相反,派生类获取多个继承的构造函数,其中连续省略具有默认参数的每个参数.

这条规则背后的原因是什么?

c++ inheritance c++11

15
推荐指数
2
解决办法
2374
查看次数

返回常量表达式不需要constexpr函数吗?

第240页的C++入门(第5版)有一条说明:

" constexpr返回常量表达式不需要函数".

有人质疑这个问题:constexpr函数的返回类型是非const吗?.这个问题的作者误解了这个说明.

但是对它的正确理解是什么(引用帖子的答案澄清了该帖子的作者的混淆,但是没有回答我的问题)?

c++ c++11

14
推荐指数
2
解决办法
2038
查看次数

是否构造了伪参数的对象参数?

假设一个功能模板:

template <class T>
void foo(T /* dummy */) {...}
Run Code Online (Sandbox Code Playgroud)

假设这样foo调用:

foo(Widget());
Run Code Online (Sandbox Code Playgroud)

Widget在这种情况下是否会构建一个对象?

这篇文章提出了一个关于未使用的参数的类似问题(虚拟参数的参数肯定未被使用).回复表明,除非通过函数指针调用函数,否则编译器将优化未使用的参数.

但是,请考虑Alexandrescu 在Modern C++的2.5节中的以下文本:

现在说你的应用程序中有一条规则:Widget类型的对象是不可触及的遗留代码,在构造时必须带两个参数,第二个是固定值,如-1.从Widget派生的您自己的类没有这个问题.

...

在没有部分专业化功能的情况下,唯一可用的工具又是重载.解决方案是传递类型为T的虚拟对象并依赖于重载:

template <class T, class U>
T* Create(const U& arg, T /* dummy */)
{
   return new T(arg);
}
template <class U>
Widget* Create(const U& arg, Widget /* dummy */)
{
   return new Widget(arg, -1);
}
Run Code Online (Sandbox Code Playgroud)

这样的解决方案将导致构造仍未使用的任意复杂对象的开销.

这表明编译器不够智能,无法避免伪参数的构造...

那么,哪个是正确的?如果Alexandrescu是正确的,那为什么不进行这种优化呢?

c++

12
推荐指数
2
解决办法
1340
查看次数

是否有更简单的方法来获取包含在智能指针中的类的成员?

为神秘的标题道歉.假设这个定义:

struct TestNode {
    using CostType = double;
};
Run Code Online (Sandbox Code Playgroud)

我希望能够像这样定义一个类模板:

template <typename NodeP,
          typename MyPolicy = /* CostType of the node type corresponding to NodeP */ >
struct TT {
};
Run Code Online (Sandbox Code Playgroud)

在上面的定义中,NodeP可以是指向定义的类的简单指针或智能指针CostType,例如TestNode.问题:如何指定MyPolicy模板参数的默认值为CostType对应的节点类型NodeP

这是我到目前为止的解决方案:

// like std::remove_pointer, but works with smart pointers as well
template <typename PT> struct my_remove_pointer {
    using type = typename
        std::remove_reference< decltype( *((PT)nullptr) ) >::type;
};

struct TestNode {
    using CostType = …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

11
推荐指数
1
解决办法
229
查看次数

为什么我可以从{}初始化常规数组,而不是std :: array

这有效:

int arr[10] = {};
Run Code Online (Sandbox Code Playgroud)

所有元素arr都被初始化为零.

为什么这不起作用:

std::array<int, 10> arr({}); 
Run Code Online (Sandbox Code Playgroud)

我从g ++(版本4.8.2)收到以下警告:

警告:缺少成员'std :: array <int,10ul> :: _ M_elems'的初始值设定项

c++ compiler-warnings aggregate-initialization c++11 g++4.8

10
推荐指数
2
解决办法
1443
查看次数

仅接受指针类型参数的模板

在看到模板可以部分专用于引用或指针类型之后,我想知道我是否可以编写一个只接受指针类型的模板.这是我的尝试:

template <typename T*>
struct MyTemplate{};

int main() {
    MyTemplate<int *> c;
    (void)c;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这不编译.应该如何修改?(即如果我想要完成的任务是可能的话)

c++ templates partial-specialization c++11

9
推荐指数
1
解决办法
1616
查看次数

实际使用C++前缀增量运算符返回左值的事实

我刚刚了解到C++中前缀增量运算符的结果是左值.有可能这种行为有助于程序员更有效,但我想不到任何.前缀增量运算符的这种行为有哪些惯用的用法?

c++ c++11

8
推荐指数
2
解决办法
297
查看次数