No, you can't use explicit, but you can use a templated function to catch the incorrect parameter types.
With C++11, you can declare the templated function as delete
d. Here is a simple example:
#include <iostream>
struct Thing {
void Foo(int value) {
std::cout << "Foo: value" << std::endl;
}
template <typename T>
void Foo(T value) = delete;
};
This gives the following error message if you try to call Thing::Foo
with a size_t
parameter:
error: use of deleted function
‘void Thing::Foo(T) [with T = long unsigned int]’
In pre-C++11 code, it can be accomplished using an undefined private function instead.
class ClassThatOnlyTakesBoolsAndUIntsAsArguments
{
public:
// Assume definitions for these exist elsewhere
void Method(bool arg1);
void Method(unsigned int arg1);
// Below just an example showing how to do the same thing with more arguments
void MethodWithMoreParms(bool arg1, SomeType& arg2);
void MethodWithMoreParms(unsigned int arg1, SomeType& arg2);
private:
// You can leave these undefined
template<typename T>
void Method(T arg1);
// Below just an example showing how to do the same thing with more arguments
template<typename T>
void MethodWithMoreParms(T arg1, SomeType& arg2);
};
The disadvantage is that the code and the error message are less clear in this case, so the C++11 option should be selected whenever available.
Repeat this pattern for every method that takes the bool
or unsigned int
. Do not provide an implementation for the templatized version of the method.
This will force the user to always explicitly call the bool or unsigned int version.
Any attempt to call Method
with a type other than bool
or unsigned int
will fail to compile because the member is private, subject to the standard exceptions to visibility rules, of course (friend, internal calls, etc.). If something that does have access calls the private method, you will get a linker error.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…