我最近从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 …
我偶然发现了这个奇怪的名称查找问题,其中基类成员函数似乎根本不参与重载选择,即使它是使用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++ 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)