【问题标题】:C++ automatic implicit conversion from const char to stringC++ 自动从 const char 到 string 的隐式转换
【发布时间】:2014-01-30 06:10:34
【问题描述】:

好吧,我只是第一次学习模板,所以我正在玩弄创建自己的模板类来模仿它的底层类型,即向量。请记住,对 push_back 的调用只是调用底层向量的 push_back 方法。

vector<string> sV;
sV.push_back("ha");       //ok: converts from const char[3] to string

Foo<string> fS;
fS.push_back("ha");      //error: const char[3] does not match the argument list

有什么办法可以解决这个问题吗?我只是想让我的模板感觉像在使用真实的东西一样自然。


编辑:这基本上是类的主体

template <typename T> class FooPtr;
template <typename T>
class Foo{
    friend class FooPtr<T>;
public:
    Foo() {data->make_shared(vector<T>); }
#ifdef INITIALIZER_LIST
    Foo(initializer_list<T>);
#endif
    void push_back(T &t) { data->push_back(t); }
    void push_back(T &&t) { data->push_back(move(t)); }
    bool empty() { if (data->size() == 0) return true; }
    FooPtr<T> insert(size_t, T&);
    T& operator[](size_t);
    T& front();
    T& back();
    FooPtr<T> begin() { return FooPtr<T>(*this); }
    FooPtr<T> end() { return FooPtr<T>(*this, data->size()); }
    void pop_back() { data->pop_back(); }
    void pop_front() { data->pop_front; }
private:
    void check(const string&, size_t = 0);
    shared_ptr<vector<T>> data;
};

【问题讨论】:

  • template void Foo::push_back(T) template void Foo::push_back(move(T)) 有答案吗?
  • @RudolphRedNose,一开始就不应该编译。
  • 请输入 push_back()...
  • 不相关(排序):除非我没看错(很可能),否则std::move(t) 应该是std::forward&lt;T&gt;(t)
  • @WhozCraig 你不认为这里的答案是错误的吗?不应该选择void push_back(T &amp;&amp;t) 接听电话吗?因为在重载解析期间调用了 std::string 的转换构造函数,因此形成的 std::string 是一个右值?

标签: c++ string type-conversion implicit-conversion


【解决方案1】:

应该能够以与 std::string 对象相同的方式接受字符串文字的方法必须具有签名

void foo( const std::string & arg )

因此,你的 Foo::push_back 必须是

void Foo::push_back( const T & arg )

【讨论】:

  • 如此简单……却又如此出色。
  • @RudolphRedNose 标准库文档包含大量信息。
【解决方案2】:

正如您在http://www.cplusplus.com/reference/vector/vector/push_back/ 看到的那样,std::vector 提供了两种重载的 push_back 方法。

一个用于 const 类型和一个用于非 const 类型。

你的第一个 push_back 成功了,因为 std::vector 提供了一个可以处理类似

类型的函数
 const char *

其中 const 是神奇的词。您的包装模板仅提供带有签名的 push_back 方法

T & t

使用以下扩展您的实施应该可以解决您的问题:

void push_back (const T& t) {data->push_back(t);}

【讨论】:

    【解决方案3】:

    您只想尝试将const char*(而不是const charchar或其他类型的char)转换为string,否则您会尝试将元素映射到STL容器/该元素的数组在 C++ 中是无意义的。

    【讨论】:

    • 很隐晦,请解释并使用标准英语。
    • 是的,非常感谢。但我认为 OP 的原始问题是缺少 const。没关系。
    【解决方案4】:

    我认为你的编译器是错误的。我的推理如下

    当你用std::string 实例化Foo 时,生成的push_back 成员函数如下

    void push_back(std::string &t) { data->push_back(t); }           --1
    void push_back(std::string &&t) { data->push_back(move(t)); }    --2
    
    如果参数是 std::string 类型的非常量左值表达式,则将选择

    1。如果参数是std::string 类型的非常量右值表达式。

    当您通过 "ha" 时,std::string 中的用户定义转换将启动,并且由于生成的 std::string (std::string("ha")) 是一个右值,因此应该选择 2。即使将 const 添加到 1 也不会导致 2 未被选中。

    来自STL 的好帖子

    【讨论】:

      猜你喜欢
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 2019-01-30
      • 2020-11-26
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多