显式转换和模板化转换运算符

时间:2011-11-10 12:48:26

标签: c++ templates operator-overloading

我想以某种方式扩展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):错误C2668:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; :: basic_string':对重载函数的模糊调用

如果删除template <typename Type> operator Type...行,则所有内容都会编译。

现在我明白了compilater所说的内容(它不知道使用哪个运算符)但我不明白为什么:转换为operator std::string时使用std::string似乎合乎逻辑。我错过了什么?

谢谢。

1 个答案:

答案 0 :(得分:1)

问题是字符串的构造函数被重载了。因此,如果返回涉及调用字符串构造函数,那么有多种选择:参数可以转换为const char*allocator<char>string

static_cast<string>(x)string(x)相同。

我认为您的第一个错误示例应该是return string(foo());,而不是return value_type(foo());