您可以使用关键字显式来阻止方法参数的自动转换吗?
-
05-07-2019 - |
题
我知道您可以将C ++关键字'explicit'用于类的构造函数,以防止类型的自动转换。您是否可以使用相同的命令来阻止类方法的参数转换?
我有两个类成员,一个将bool作为参数,另一个是unsigned int。当我用int调用函数时,编译器将param转换为bool并调用错误的方法。我知道最终我会替换bool,但是现在不想破坏其他例程,因为这个新例程已经开发出来了。
解决方案
不,你不能使用显式,但你可以这样做:
class ClassThatOnlyTakesBoolsAndUIntsAsArguments
{
public:
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:
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);
};
对于采用bool
或unsigned int
的每个方法重复此模式。不要为方法的模板化版本提供实现。
这将强制用户始终显式调用bool或unsigned int版本。
任何使用Method
或<=>以外的类型调用<=>的尝试都将无法编译,因为该成员是私有的,当然受制于可见性规则的标准例外(朋友,内部调用等) )。如果具有访问权限的东西调用私有方法,则会出现链接器错误。
其他提示
没有。 explicit
阻止特定类之间的自动转换,无论上下文如何。当然,你无法为内置类做到这一点。
以下是一个非常基本的包装器,可用于创建强大的typedef:
template <typename V, class D>
class StrongType
{
public:
inline explicit StrongType(V const &v)
: m_v(v)
{}
inline operator V () const
{
return m_v;
}
private:
V m_v; // use V as "inner" type
};
class Tag1;
typedef StrongType<int, Tag1> Tag1Type;
void b1 (Tag1Type);
void b2 (int i)
{
b1 (Tag1Type (i));
b1 (i); // Error
}
这种方法的一个很好的特点是,您还可以区分具有相同类型的不同参数。例如,您可以拥有以下内容:
class WidthTag;
typedef StrongType<int, WidthTag> Width;
class HeightTag;
typedef StrongType<int, HeightTag> Height;
void foo (Width width, Height height);
'foo'的客户会清楚哪个参数是哪个。
可能对您有用的是使用模板。以下显示模板函数foo<>()
专门用于bool
,unsigned int
和int
。 main()
函数显示如何解析调用。请注意,使用未指定类型后缀的常量foo<int>()
的调用将解析为foo( 1)
,因此如果您不专注于"U"
,则会出现调用<=>的错误。如果是这种情况,使用文字整数常量的调用者必须使用<=>后缀来获取要解析的调用(这可能是您想要的行为)。
否则你必须专注于<=>并使用<=>后缀或将其转换为<=>,然后再将其传递给<=>版本(或者可以断言值为n')如果这是你想要的,那就是否定的。
#include <stdio.h>
template <typename T>
void foo( T);
template <>
void foo<bool>( bool x)
{
printf( "foo( bool)\n");
}
template <>
void foo<unsigned int>( unsigned int x)
{
printf( "foo( unsigned int)\n");
}
template <>
void foo<int>( int x)
{
printf( "foo( int)\n");
}
int main ()
{
foo( true);
foo( false);
foo( static_cast<unsigned int>( 0));
foo( 0U);
foo( 1U);
foo( 2U);
foo( 0);
foo( 1);
foo( 2);
}
编译器给出了<!>“不明确的呼叫<!>”;警告,这就足够了。
我正在进行TDD开发,并没有意识到我忘了在模拟对象中实现相应的调用。
bool是一个限制为0或1的int。这是return 0的整个概念;它在逻辑上与返回false相同;(不要在代码中使用它)。
你也可以写一个调用bool的int版本。