小编Mar*_*rio的帖子

为什么我更喜欢明确给出类型的"显式类型化初始化器"习惯用法

我最近从Scott Meyers那里购买了新的Effective现代C++,现在正在阅读它.但是我遇到了一件事,这完全让我感到烦恼.

斯科特在第5项中说,使用auto是一件好事.它可以节省打字,在大多数情况下会为您提供正确的类型,并且可能不会出现类型不匹配的情况.我完全理解这一点,并认为这也是auto一件好事.

但是在第6项中斯科特告诉我,每枚硬币都有两面.同样可能存在一些情况,例如auto推断完全错误的类型,例如代理对象.

您可能已经知道这个例子:

class Widget;
std::vector<bool> features(Widget w);

Widget w;

bool priority = features(w)[5]; // this is fine

auto priority = features(w)[5]; // this result in priority being a proxy
                                // to a temporary object, which will result
                                // in undefined behavior on usage after that
                                // line
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.

但斯科特对此的解决方案是所谓的"明确类型化的初始化器成语".这个想法是,在初始化器上使用static_cast,如下所示:

auto priority = static_cast<bool>(features(w)[5]);
Run Code Online (Sandbox Code Playgroud)

但这不仅会导致更多的输入,而且还会明确说明应该推断出的类型.你基本上失去了auto超过明确给定类型的优点.

任何人都可以告诉我,为什么使用这个成语是有利的?


首先要澄清一下,我的问题旨在为什么要写:

auto priority = static_cast<bool>(features(w)[5]);
Run Code Online (Sandbox Code Playgroud)

代替:

bool priority = features(w)[5];
Run Code Online (Sandbox Code Playgroud)

@Sergey提出了一个关于GotW关于这个主题的好文章的链接,这部分回答了我的问题.

指南:考虑声明局部变量auto …

c++ effective-c++ c++11

43
推荐指数
3
解决办法
2233
查看次数

enable_if'd继承的成员函数的名称查找错误

我偶然发现了这个奇怪的名称查找问题,其中基类成员函数似乎根本不参与重载选择,即使它是使用using语句导入的.基类和派生类的成员函数都是SFINAE'd enable_if_t.

我能够使用以下代码重现我的问题:https://gcc.godbolt.org/z/ueQ-kY

#include <iostream>
#include <type_traits>

class MyTag {};

struct Base
{
    template <typename RType>
    std::enable_if_t<std::is_convertible<RType, int>::value> create(RType /*&&*/ ref)
    {
        std::cout << "Base::create(RType ref)" << std::endl;
    }
};

struct Derived : Base
{
    using Base::create;

    template <typename Tag>
    std::enable_if_t<std::is_same<Tag, MyTag>::value> create(Tag /*&&*/ tag)
    {
        std::cout << "Derived::create(Tag tag)" << std::endl;
    }
};

int main()
{
    Derived d;

    d.create(MyTag());
    d.create(0); // [x86-64 clang 7.0.0 #1] error: no matching member function for call to …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

7
推荐指数
1
解决办法
118
查看次数

隐式与显式删除的复制构造函数

我最近在我的C++ 11代码中遇到了一些奇怪的行为.

我有一个班级,只能移动:

class only_move
{
public:

    only_move() :  value(0) {}

    only_move(int value) : value(value) {}

    only_move(const only_move&) = delete;
    only_move& operator=(const only_move&) = delete;

    only_move(only_move&&) = default;
    only_move& operator=(only_move&&) = default;

    int value;
};
Run Code Online (Sandbox Code Playgroud)

我有另一个类,其中包含一个only_move对象:

class has_only_move_member
{
public:

    has_only_move_member() = delete;

    has_only_move_member(only_move&& value) : member(std::move(value)) {}

    only_move member;
};
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,那意味着has_only_move_member无法复制,因为该only_move成员无法复制.has_only_move_member(const has_only_move_member&)隐含地删除此方法.我们来看看:

has_only_move_member object(only_move(5));
has_only_move_member copy_of_object(object);
Run Code Online (Sandbox Code Playgroud)

正如所料,它打印出:

error: use of deleted function ‘has_only_move_member::has_only_move_member(const has_only_move_member&)’
note: ‘has_only_move_member::has_only_move_member(const has_only_move_member&)’ is implicitly deleted because …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

6
推荐指数
1
解决办法
1518
查看次数

标签 统计

c++ ×3

c++11 ×2

effective-c++ ×1

language-lawyer ×1