Joh*_*ing 4 c++ implicit-conversion auto c++11
容器需要提供一种iterator可隐式转换为a 的类型const_iterator.鉴于此,我尝试使用auto初始化对象vector::begin(),并std::distance在RHS所在的位置使用该结果对象const_iterator.这不起作用.这是一个完整的例子:
#include <cstdlib>
#include <vector>
#include <iterator>
#include <iostream>
typedef std::vector <char> Packet;
typedef std::vector <Packet> Packets;
template <typename Iter>
Iter next_upto (Iter begin, Iter end, size_t n)
{
Iter ret = begin;
for (; n > 0 && ret != end; ++ret, --n)
;
return ret;
}
Packets::const_iterator Process (Packets::const_iterator begin, Packets::const_iterator end)
{
Packets::const_iterator ret = begin;
while (ret != end)
++ret; // do something
return ret;
}
int main()
{
Packets test (100); // vector of 100 default-initialized packets
// process them 10 at a time
for (auto it = test.begin();
it != test.end();
it = next_upto (it, test.end(), 10))
{
auto itr = Process (it, next_upto (it, test.end(), 10));
Packets::const_iterator it2 = it;
const size_t n1 = std::distance (it2, itr);
const size_t n = std::distance (it, itr);
std::cout << "Processed " << n << " packets\n";
}
}
Run Code Online (Sandbox Code Playgroud)
在g ++ 4.8.1(和4.8.2)下编译,得到:
[1/2] Building CXX object CMakeFiles/hacks.dir/main.o
FAILED: /usr/bin/g++ -Wall -std=c++11 -g -MMD -MT CMakeFiles/hacks.dir/main.o -MF "CMakeFiles/hacks.dir/main.o.d" -o CMakeFiles/hacks.dir/main.o -c main.cpp
main.cpp: In function ‘int main()’:
main.cpp:39:45: error: no matching function for call to ‘distance(__gnu_cxx::__normal_iterator<std::vector<char>*, std::vector<std::vector<char> > >&, __gnu_cxx::__normal_iterator<const std::vector<char>*, std::vector<std::vector<char> > >&)’
const size_t n = std::distance (it, itr);
^
main.cpp:39:45: note: candidate is:
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:66:0,
from /usr/include/c++/4.8/vector:60,
from main.cpp:2:
/usr/include/c++/4.8/bits/stl_iterator_base_funcs.h:114:5: note: template<class _InputIterator> typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator)
distance(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/4.8/bits/stl_iterator_base_funcs.h:114:5: note: template argument deduction/substitution failed:
main.cpp:39:45: note: deduced conflicting types for parameter ‘_InputIterator’ (‘__gnu_cxx::__normal_iterator<std::vector<char>*, std::vector<std::vector<char> > >’ and ‘__gnu_cxx::__normal_iterator<const std::vector<char>*, std::vector<std::vector<char> > >’)
const size_t n = std::distance (it, itr);
^
Run Code Online (Sandbox Code Playgroud)
我知道,我可以通过调用解决这种特定情况下cbegin()和cend(),而不是begin()和end(),但由于begin()并end()返回一个类型,应该是转换为const_iterator,我不知道我理解为什么这是必要的.
为什么auto在这种情况下推导出一种不可转换的类型const_iterator?
Pra*_*ian 19
您的问题可以简化为以下示例,由于相同的原因,该示例失败.
#include <vector>
#include <iterator>
int main()
{
std::vector<int> v;
std::vector<int>::const_iterator it1 = v.begin();
auto it2 = v.end();
auto n = std::distance(it1, it2);
}
Run Code Online (Sandbox Code Playgroud)
std::distance两个参数使用相同的模板参数类型定义,并且模板参数推断失败,因为您有一个const_iterator和iterator.
在从函数调用中推导出模板参数时,不考虑用户定义的转换,并且由于这两个参数在这种情况下具有不同的类型,并且两者都参与模板参数推导,因此推导失败.
§14.8.1/ 6 [temp.arg.explicit]
如果参数类型不包含参与模板参数推导的模板参数,则将对函数参数执行隐式转换(第4节)以将其转换为相应函数参数的类型.
§14.8.2.1/ 4 [temp.over]
...[ 注意:如14.8.1中所指定的,如果参数不包含参与模板参数推断的模板参数,则将对函数参数执行隐式转换,以将其转换为相应函数参数的类型.除了前面列表中描述的转换之外,还允许这样的转换.- 尾注 ]
您需要将to转换iterator为const_iterator,或者明确指定模板参数std::distance.
auto n = std::distance(it1, static_cast<decltype(it1)>(it2));
Run Code Online (Sandbox Code Playgroud)
要么
auto n = std::distance<decltype(it1)>(it1, it2);
Run Code Online (Sandbox Code Playgroud)
当然,其他选项是auto在两种情况下都不使用和显式指定迭代器类型,或者在需要确保类型为a时使用vector::cbegin()和vector::cend()成员函数const_iterator.
| 归档时间: |
|
| 查看次数: |
1456 次 |
| 最近记录: |