我有一个CFixedLengthString
类模板,只有数据成员。数据成员的大小由模板类型参数确定。
template<size_t _Length>
class CFixedLengthString
{
private:
char Buffer[_Length];
public:
// Has constructors, conversion operators etc.
// Listing the important ones
operator const char*();
operator = (const CFixedLengthString&);
operator = (const char*);
};
自动转换是为了方便。例子:
CFixedLengthString<10> buf;
buf = "SomeString";
strlen(buf);
但是这种便利也允许以下操作成功:
CFixedLengthString<10> buf1;
CFixedLengthString<20> buf2;
buf1 = buf2;
这里通过隐式转换运算符buf2
转换为,并用 . 调用。并因此转换为.const char*
operator=
const char*
<20>
<10>
重要的东西在这里。
为此,我编写了一个赋值运算符,它具有CFixedLengthString
不同的大小。
template<size_t _TOtherSize>
void operator=(const CFixedLengthString<_TOtherSize>&);
而且,当然,将其设为 private,因此如果<20>
转换为<non-20>
. 但是,令我惊讶的是,编译器并没有抱怨!它允许调用这个私人运营商!
如果<N>
被复制到<N>
,它调用正常的赋值操作符。如果<N>
被复制(分配)给<M>
编译器,则调用此专用操作符。
但是为什么编译器允许在这种情况下调用私有(以及受保护)?我正在使用 VC2008 编译器。我只为这个编译器寻找解决方案。
现在,我已经在这个专门的函数的主体中编写了一个静态断言(为了禁止这种错误的转换)。
编辑: 所有的回应都在欣赏。我唯一的问题是:
- 为什么我放在
private
区域的专用版本是可调用的?
我们都使用私有、仅声明函数、delete
属性和其他方面进行防御性编程。我正在尝试做同样的事情。但是编译器允许调用私有函数!
编辑2: 示例代码:
template<size_t SIZE>
class FixedString
{
public:
operator const char*();
void operator =(const char*);
void operator =(const FixedString&);
// Disallow
private:
template<size_t OTHERSIZE>
void operator=(const FixedString<OTHERSIZE>&);
};
int main()
{
FixedString<10> buf1;
FixedString<20> buf2;
buf2 = buf1; // NO ERROR!!
}
如果我删除 的专用版本operator=
,它仍然可以工作。我想避免这种情况!