Explicit bool operator - cannot return, test, initialize bool

浪尽此生 提交于 2019-12-13 05:13:11

问题


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

The convertible class would e.g. be a smart pointer class with the ability to check for the validity of the contained data.

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 ‘bool’ in return
  return test;
          ^
test.cpp: In function ‘bool testReturn2()’:
test.cpp:22:15: error: no match for ‘operator==’ (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 ‘bool’ in initialization
  bool tested = test;

With Clang it's similar:

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.

回答1:


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

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) )
}

You could also delete all types except which are explicitly overloaded using a templated version of the conversion operator:

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:


If your cast operator is explicit, you need to cast it, something like:

return static_cast<bool>(test);


来源:https://stackoverflow.com/questions/21350924/explicit-bool-operator-cannot-return-test-initialize-bool

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!