相关疑难解决方法(0)

错误检查的转换功能被认为是好的?

我想有一个简单的方法来检查对象是否有效.我想到了一个简单的转换函数,如下所示:

operator bool() const { return is_valid; }
Run Code Online (Sandbox Code Playgroud)

检查它是否有效现在非常简单

// is my object invalid?
if (!my_object) std::cerr << "my_object isn't valid" << std::endl;
Run Code Online (Sandbox Code Playgroud)

这被认为是一种好习惯吗?

c++ error-handling

49
推荐指数
2
解决办法
3057
查看次数

c++ nullptr 实现是如何工作的?

我很想知道它是如何nullptr工作的。标准 N4659 和 N4849 说:

  1. 它必须有类型std::nullptr_t
  2. 你不能拿它的地址;
  3. 可以直接转换为指针和成员指针;
  4. sizeof(std::nullptr_t) == sizeof(void*);
  5. 其转换boolfalse;
  6. 它的值可以转换为与 相同的整数类型(void*)0,但不能向后转换;

所以它基本上是一个与 具有相同含义的常量(void*)0,但它具有不同的类型。我std::nullptr_t在我的设备上找到了实现,如下所示。

#ifdef _LIBCPP_HAS_NO_NULLPTR

_LIBCPP_BEGIN_NAMESPACE_STD

struct _LIBCPP_TEMPLATE_VIS nullptr_t
{
    void* __lx;

    struct __nat {int __for_bool_;};

    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}

    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}

    template <class _Tp>
        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
        operator _Tp* () const {return 0;}

    template <class _Tp, class …
Run Code Online (Sandbox Code Playgroud)

c++ null-pointer nullptr c++17

19
推荐指数
1
解决办法
954
查看次数

删除cout; 删除cin; 不要给出编译错误 - 标准库中的缺陷?

以下是否会出现编译错误?

delete cout;
delete cin;
Run Code Online (Sandbox Code Playgroud)

答案是不.

它是标准库中流类实现的一个缺陷.它们具有以下要转换的转换函数void*,这意味着,所有流对象都可以隐式转换为void*:

operator void * ( ) const;
Run Code Online (Sandbox Code Playgroud)

这一般非常有用,因为它可以让我们在从文件读取输入时编写非常惯用的循环.但与此同时,它让用户可以写delete stream.正如我所说,您可以删除任何流对象.所以这些都是允许的:

delete ss;  //declare std::stringstream ss;
delete iss; //declare std::istringstream iss;
delete oss; //declare std::ostringstream oss;
Run Code Online (Sandbox Code Playgroud)

只有他们会发出警告,说(见ideone):

警告:删除'void*'未定义

你可以轻易地通过铸造来避免,比如说char*.但该程序仍然存在问题,并且在运行时很可能会崩溃.

-

所以我的问题是,在C++ 11中这个问题已得到解决和修复吗?以下文章提供了此问题的一个修复:

-

编辑:

来自@ Xeo对@ Alf答案的评论:

提出修复此问题的论文:

c++ stream implicit-conversion c++11

14
推荐指数
1
解决办法
920
查看次数

如果使用g ++,为什么std :: cout可以转换为void*?

为什么一个能投射出std::ostreamvoid指针?我不知道有任何这样的转换运算符std::ostream.代码如下

#include <iostream>

int main()
{
    void *p = std::cout; // why does this work? 
}
Run Code Online (Sandbox Code Playgroud)

我问这个问题,因为我已经看到new调用了一个放置操作符

Foo* pFoo = new (std::cerr) Foo;
Run Code Online (Sandbox Code Playgroud)

并且完全不知道为什么会写这样的东西.

PS:我正在使用或不使用g ++ 4.9.2进行编译-std=c++11.clang ++ 不接受代码.

PSS:发现由于所谓的"安全bool问题"(参见@ nicebyte的回答),在预C++ 11 void*中定义了一个转换运算符std::ostream,然后在C++ 11中将其删除.但是,我的代码使用g ++在C++ 11中编译得很好.更重要的是,clang ++拒绝它,无论我使用什么版本的标准,即使有-std=c++98,尽管我的理解是它应该接受,如果编译为pre-C++ 11.

c++ pointers ostream implicit-conversion

13
推荐指数
1
解决办法
349
查看次数

为什么operator void*()转换函数被添加到C++流类中?

operator void*() constC++流类中有一个转换函数.这样所有流对象都可以隐式转换为void*.在与SO的程序员交互过程中,他们建议我不要使用,void*除非你有充分的理由使用它.void*是一种删除类型安全和错误检查的技术.因此,由于该转换功能的存在,以下程序完全有效.这是C++标准库中的一个缺陷.

#include <iostream>
int main()
{
       delete std::cout;
       delete std::cin;
}
Run Code Online (Sandbox Code Playgroud)

在这里查看现场演示.

上述程序在C++ 03中有效,但在C++ 11及更高版本的编译器中编译失败,因为此转换函数已被删除.但问题是,如果它是危险的,它是C++标准库的一部分?允许将流对象转换为的目的是void*什么?有什么用?

c++ void-pointers c++-standard-library delete-operator c++11

13
推荐指数
2
解决办法
1902
查看次数

QScopedPointer中运算符RestrictedBool的用途是什么?

我一直在阅读代码,QScopedPointer并发现了一些我无法理解的东西.

这是QScopedPointercode.qt.io 上的相关代码:

template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
    typedef T *QScopedPointer:: *RestrictedBool;
public:
...
#if defined(Q_QDOC)
    inline operator bool() const
    {
        return isNull() ? Q_NULLPTR : &QScopedPointer::d;
    }
#else
    inline operator RestrictedBool() const
    {
        return isNull() ? Q_NULLPTR : &QScopedPointer::d;
    }
#endif
...
inline bool isNull() const
{
    return !d;
}
...
protected:
    T *d;
Run Code Online (Sandbox Code Playgroud)

我理解使QDoc认为QScopedPointer具有的预处理器定义operator bool而不是operator RestrictedBool.我不明白它的用途RestrictedBool是什么以及它是如何做到的.例如,更简单的实现是:

inline operator bool() const …
Run Code Online (Sandbox Code Playgroud)

c++ qt qt5

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

为什么iostream对象不会超载operator bool?

这个答案中,我谈到使用std::ifstream对象的转换bool来测试流是否仍处于良好状态.我查看了Josuttis的书以获取更多信息(如果你感兴趣,请查看600页),事实证明这些iostream物体实际上已超载operator void*.当流不好(可以隐式转换为false)时返回空指针,否则返回非空指针(隐式转换为true).他们为什么不过载operator bool

c++ iostream operator-overloading

9
推荐指数
2
解决办法
3674
查看次数

当一个对象同时提供`operator!`和`operator bool`时,它在表达式`!obj`中使用?

我遇到了一个我无法自己回答的问题.此外,我没有在谷歌和这里找到答案.比如,我想在if子句中"检查对象的有效性",如下所示:

MyClass myObject;

// [some code, if any]

if (!myObject)
{
    // [do something]
}
Run Code Online (Sandbox Code Playgroud)

我们MyClass这样定义:

class MyClass
{
public:
    MyClass() { };
    virtual ~MyClass() { };
    bool operator!()
    {
        return !myBool;
    };
    operator bool()
    {
        return myBool;
    };
private:
    bool myBool = 0;
};
Run Code Online (Sandbox Code Playgroud)

我现在的问题是:在这个if子句中实际使用了哪一个重载运算符?无论哪种方式,结果显然都是一样的.

c++ overloading operator-keyword

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

isSet()或operator void*()或显式opertor bool()还是其他什么?

什么是最先进的大约功能检查值是否设置与否

例如,下面的迭代器解析单元格.一些单元格包含值,其他单元格为空.

什么是最方便的方式?

struct iterator 
{                                  //usage:
  bool isset() const               // if (it.isset()) 
  bool isSet() const               // if (it.isSet()) 
  bool empty() const               // if (it.empty()) 

  bool is_set()   const            // if (it.is_set()) 
  bool is_valid() const            // if (it.is_valid()) 

  operator void*() const;          // if (it) 

  explicit operator bool() const;  // if ((bool)it) or if(it) //thanks @stijn
  operator          bool() const;  // if (it) //why not implicit conversion?

  bool operator!() const;          // if (!!it)

  //throwing exception as pointed out by …
Run Code Online (Sandbox Code Playgroud)

c++ operator-keyword explicit-conversion c++11 c++03

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

istringstream运算符>>返回值如何工作?

此示例使用整数,运算符和另一个整数读取行.例如,

25*3

4/2

// sstream-line-input.cpp - Example of input string stream.
//          This accepts only lines with an int, a char, and an int.
// Fred Swartz 11 Aug 2003

#include <iostream>
#include <sstream>
#include <string>
using namespace std;
//================================================================ main
int main() {
    string s;                 // Where to store each line.
    int    a, b;              // Somewhere to put the ints.
    char   op;                // Where to save the char (an operator)
    istringstream instream;   // Declare an input string stream

    while …
Run Code Online (Sandbox Code Playgroud)

c++

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