问题
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