Explicit bool statement - cannot return, check, initialize bool

I just tried to use it explicit operator bool()for the first time, and its behavior is completely unexpected for me. Can someone shed light on why the following sections are marked // does not work.

The class convertiblewill, for example, be a class of smart pointers with the ability to validate the data contained.

struct convertible
{
  explicit operator bool() const
  {
    return ptr;
  }

  void* ptr = nullptr;
};

bool testReturn()
{
  convertible test;
  // does not work
  return test;
}

bool testReturn2()
{
  convertible test;
  // does not work
  return test == true;
}

bool testReturn3()
{
  convertible test;
  // works ?!
  return !test;
}

int main()
{
  convertible test;
  // works
  if (test) { }
  // works
  bool init(test);
  bool tested = test;
  bool tested2 = testReturn();
  bool tested3 = testReturn2();
  bool tested4 = testReturn3();
  return 0;
}

With GCC, I get:

milian@minime:/tmp$ g++ --version
g++ (GCC) 4.8.2 20131219 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

milian@minime:/tmp$ g++ -std=c++11 test.cpp 
test.cpp: In function ‘bool testReturn()’:
test.cpp:15:10: error: cannot convert ‘convertible’ to ‘boolin return
  return test;
          ^
test.cpp: In function ‘bool testReturn2()’:
test.cpp:22:15: error: no match foroperator==’ (operand types are ‘convertible’ and ‘bool’)
  return test == true;
              ^
test.cpp:22:15: note: candidate is:
test.cpp:22:15: note: operator==(int, int) <built-in>
test.cpp:22:15: note:   no known conversion for argument 1 from ‘convertible’ to ‘int
test.cpp: In function ‘int main()’:
test.cpp:39:17: error: cannot convert ‘convertible’ to ‘boolin initialization
  bool tested = test;

With Clang, it looks like:

milian@minime:/tmp$ clang++ --version
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
milian@minime:/tmp$ clang++ -std=c++11 test.cpp 
test.cpp:15:10: error: no viable conversion from 'convertible' to 'bool'
  return test;
        ^~~~
test.cpp:22:15: error: invalid operands to binary expression ('convertible' and 'int')
  return test == true;
        ~~~~ ^  ~~~~
test.cpp:39:8: error: no viable conversion from 'convertible' to 'bool'
  bool tested = test;
      ^        ~~~~
3 errors generated.
0
source share
2 answers

If your goal is to disable certain transformations, just disable them through the specifier delete:

struct convertible
{
    operator bool() const //(Implicit) Conversion to bool allowed
    {
        return true;
    }

    operator int() const = delete; //Implicit/Explicit conversions to int disallowed 
                                   //(Results in compilation error).
};


int main()
{
    convertible c;

    if( c )
        ...

    int a = c; //ERROR
    int b = (int)c; //ERROR (The same for static_cast<int>(c) )
}

, :

struct foo
{
    operator bool() const //Explicit overload for bool
    {
       return true; 
    }

  template<typename T>
  operator T() const = delete; //Everithing which is not a bool (Everithing which  
                               //does not fit in the explicit overload) would  
                               //resolve to this operator and will fail.
};


int main()
{
    foo f;

    bool b = f; //OK
    int i = f;  //ERROR
    char c = f; //ERROR
    etc...
}
+2

explicit, , :

return static_cast<bool>(test);
0

Source: https://habr.com/ru/post/1523698/


All Articles