从 const char* 到迭代器错误的“未知转换” - 另一种方法

Posted

技术标签:

【中文标题】从 const char* 到迭代器错误的“未知转换” - 另一种方法【英文标题】:The "no known conversion" from const char* to an iterator error - another take 【发布时间】:2016-04-12 13:45:52 【问题描述】:

我正在做以下事情:

using namespace boost;
const char* line = // ...
size_t line_length = // ...
// ...
tokenizer<escaped_list_separator<char> > line_tokenizer(
    line, line + line_length,
    escaped_list_separator<char>('\\', ',', '\"'));

期望使用boost::tokenizer 构造函数

tokenizer(Iterator first, Iterator last,
          const TokenizerFunc& f = TokenizerFunc()) 
  : first_(first), last_(last), f_(f)  

但是 GCC 4.9.3 给了我:

no known conversion for argument 1 from ‘const char*’ to ‘__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >’

现在,我看到几个related questions 的答案是忘记#include &lt;algorithm&gt; - 但我已经 包含了它。是否还有其他一些缺失的包含,或者是另一个问题?

【问题讨论】:

请提供minimal reproducible example。 @Barry:它简洁、完整,不能机器验证,但我认为它是可以合理验证的。 在我们编译和重现您的错误(然后消除它并告诉您我们做了什么)之前,它是不完整和可验证的。 【参考方案1】:

正如编译器错误所说,没有办法从 const char* 构建迭代器。您可以使用 std::string:

修复它
std::string line = "some string";
// ...
tokenizer<escaped_list_separator<char> > line_tokenizer(
    line.begin(), line.end(),
    escaped_list_separator<char>('\\', ',', '\"'));

【讨论】:

这是在性能关键代码中,所以我不想开始将我的字符串复制到 std::string 的缓冲区中。我会使用 GSL string_viewstring_span 或他们所说的任何名称,但我不想包含整个 GSL。您能提出一个解决方法吗? 此外,许多标准库算法将一对指针作为迭代器对,例如std::copy;那为什么不是这个东西呢? 此标记器构造函数采用 Iterator(实际上是 std::string::const_iterator),因此在这种情况下您不能使用原始 char* 指针。【参考方案2】:

如果您不想使用容器作为搜索空间,则必须手动构建令牌迭代器

#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>

int main()

    const char xx[] = "a,b,c,d,e,f,g";
    auto line = xx;
    size_t line_length = strlen(line);

    using namespace boost;

    auto f = escaped_list_separator<char>('\\', ',', '\"');
    auto beg = make_token_iterator<char>(line ,line + line_length,f);
    auto end = make_token_iterator<char>(line + line_length,line + line_length,f);
    // The above statement could also have been what is below
    // Iter end;
    for(;beg!=end;++beg)
        std::cout << *beg << "\n";
    
    return 0;

【讨论】:

【参考方案3】:

由于您使用的是 boost,您可以这样做:

#include <boost/utility/string_ref.hpp>
// ...
const boost::string_ref line_(line, line_length);
tokenizer<escaped_list_separator<char> > line_tokenizer(
    line_, escaped_list_separator<char>('\\', ',', '\"'));

这似乎有效。阅读有关string_ref 和其他实用程序here 的更多信息。

当然,如果您有指南支持库的实现,请从那里使用string_span(又名string_view)(here 的一个实现)。它甚至可能会进入标准库。

更新:string_view 在 C++17 的 C++ 标准中。现在你可以写了:

#include <string_view>
// ...
std::string_view line_  line, line_length ;
tokenizer<escaped_list_separator<char> > line_tokenizer(
    line_, escaped_list_separator<char>('\\', ',', '\"'));

【讨论】:

以上是关于从 const char* 到迭代器错误的“未知转换” - 另一种方法的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的错误,错误:从‘const char*’到‘char’的无效转换[-fpermissive]

我收到从 char 到 const char 错误的无效转换。如何修复这个程序?

从 const 方法返回一对向量迭代器

std::string 生成链接器错误—— const char* 不会。为啥?

从'const char *'到'char *'的无效转换[-fpermissive]; VTK-7.1.1编译错误

错误 C2440:“=”:无法从“const char *”转换为“char *”