有点随意的问题...
我正在寻找的是一种表达强制转换操作的方法,该操作使用我正在强制转换的类实例的已定义运算符,如果没有为该类型定义的强制转换运算符,则会生成编译时错误.因此,例如,我正在寻找的是:
template< typename RESULT_TYPE, typename INPUT_TYPE >
RESULT_TYPE operator_cast( const INPUT_TYPE& tValue )
{
return tValue.operator RESULT_TYPE();
}
// Should work...
CString sString;
LPCTSTR pcszString = operator_cast< LPCTSTR >( sString );
// Should fail...
int iValue = 42;
DWORD dwValue = operator_cast< DWORD >( iValue );
有趣的旁注:上面的代码使 VS2005 C++ 编译器崩溃,并且由于我猜测是编译器错误而无法在 VS2008 C++ 编译器中正确编译,但希望能证明这个想法。
有人知道有什么方法可以达到这种效果吗?
编辑:更多的理由,解释为什么你可以使用它。假设您有一个包装类,它应该封装或抽象一个类型,并且您正在将其转换为封装的类型。您可以使用 static_cast<>,但是当您希望它失败时这可能会起作用(即:编译器选择一个允许转换为您要求的类型的运算符,当您希望失败时因为该运算符不存在)。
诚然,这是一个不常见的情况,但令人恼火的是,我无法准确表达我希望编译器在封装函数中执行的操作...因此出现了这里的问题。
最佳答案
您发布的代码适用于 Cameau compiler (这通常很好地表明它是有效的 C++)。
如您所知,一个有效的类型转换只包含一个用户定义的类型转换,因此我想到的一个可能的解决方案是通过在类型转换模板中定义一个新类型并使用 static assert 添加另一个用户定义的类型转换。从新类型到结果类型的转换不可用(使用 boost is_convertible ),但是这不区分转换运算符和转换构造函数(带有一个参数的 ctor)并且允许进行额外的转换(例如 void*
到 bool
)。我不确定区分强制转换运算符和强制转换构造函数是否是正确的事情,但这就是问题所述。
在考虑了几天之后,我突然想到,您可以简单地获取类型转换运算符(operator)的地址。由于 C++ 指向成员语法的毛茸茸的指针,这说起来容易做起来难(我花了比预期更长的时间才能正确完成)。我不知道这是否适用于 VS2008,我只在 Cameau 上检查过。
template< typename Res, typename T>
Res operator_cast( const T& t )
{
typedef Res (T::*cast_op_t)() const;
cast_op_t cast_op = &T::operator Res;
return (t.*cast_op)();
}
编辑:我有机会在 VS2005 和 VS2008 上对其进行测试。我的发现与原始海报的不同。
- 在 VS2008 上,原始版本似乎工作正常(我的也是)。
- 在 VS2005 上,原始版本仅在提供编译错误后从内置类型进行转换(例如将 int 转换为 int)时使编译器崩溃,这对我来说似乎还不错,而且我的版本似乎在所有情况下都有效。
关于c++ - 有什么方法可以只使用类运算符进行转换吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/209793/