【发布时间】:2011-11-10 12:48:26
【问题描述】:
我想以某种方式扩展 Microsoft 类型 _variant_t,以便它接受与其他类型的隐式/显式转换。为此,我编写了以下类:
class value_type
{
public:
/* Constructors */
value_type(const std::string& str) : m_variant(str.c_str()) {}
template <typename Type> value_type(const Type& value) : m_variant(value) {}
/* Conversion operators */
operator const _variant_t&() const { return m_variant; }
operator std::string() const { return static_cast<const char*>(m_variant); }
template <typename Type> operator Type() const { return static_cast<Type>(m_variant); }
private:
_variant_t m_variant;
};
也就是说,如果代码中_variant_t 的每个实例都替换为value_type,它“工作”是一样的。
让我们考虑以下函数,它返回一个_variant_t:
_variant_t foo();
如果我写:
std::string bar()
{
value_type v = foo();
return v;
}
它编译得很好。
但是如果我像这样更改以前的代码:
std::string bar()
{
return value_type(foo());
}
或:
std::string bar()
{
return static_cast<std::string>(value_type(foo()));
}
编译失败并显示以下消息:
configuration.cpp(41) : error C2668: 'std::basic_string<_elem>::basic_string' : 对重载函数的模糊调用
如果我删除 template <typename Type> operator Type... 行,一切都会编译。
现在我明白了编译器的意思(它不知道要使用哪个运算符)但我不明白为什么:在转换为 std::string 时使用 operator std::string 似乎是合乎逻辑的。我错过了什么?
谢谢。
【问题讨论】:
-
根据我对标准某些段落(主要是13.3.3.1和14.5.5.2)的(有限)理解,我会说你的代码是正确的,但我可能忽略了一些东西。您是否尝试过专门化模板转换运算符而不是重载它?
标签: c++ templates operator-overloading