【问题标题】:Explicit conversion and templated conversion operator显式转换和模板化转换运算符
【发布时间】: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 &lt;typename Type&gt; operator Type... 行,一切都会编译。

现在我明白了编译器的意思(它不知道要使用哪个运算符)但我不明白为什么:在转换为 std::string 时使用 operator std::string 似乎是合乎逻辑的。我错过了什么?

谢谢。

【问题讨论】:

  • 根据我对标准某些段落(主要是13.3.3.1和14.5.5.2)的(有限)理解,我会说你的代码是正确的,但我可能忽略了一些东西。您是否尝试过专门化模板转换运算符而不是重载它?

标签: c++ templates operator-overloading


【解决方案1】:

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

static_cast&lt;string&gt;(x)string(x) 相同。

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

【讨论】:

  • 我猜你对“为什么”是正确的。但我不能写std::string(foo()),因为std::string::string() 没有重载,它将_variant_t 作为第一个参数。
  • 我的意思是 return value_type(foo()); 似乎没问题(使用 g++)。
  • 不幸的是,这不是一个错字。我正在使用 VC10,但它在那里失败了。
猜你喜欢
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 2020-10-14
  • 2013-05-05
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
  • 2018-04-07
相关资源
最近更新 更多