STL vector.insert method expects _InputIterator as the arguments - c++

I have the following code:
typedef unsigned long int U64;
std::vector<U64> vectorA;
std::vector<U64> vectorB;
vectorA.insert(vectorA.end(), vectorB.begin(), vectorB.end());
I'm getting compilation error at the last line, it could not find the method.
It expects following signature (code from stl_vector.h):
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
iterator
insert(const_iterator __position, _InputIterator __first,
_InputIterator __last)
How can I get the instance of the _InputIterator / _RequireInputIter for the instance of vector class?
Can I do the same using different method?
I'm using gcc:
gcc version 7.0.1 20170407 (experimental) [trunk revision 246759]
(Ubuntu 7-20170407-0ubuntu2)
and Ubuntu:
NAME="Ubuntu" VERSION="17.04 (Zesty Zapus)"
edit:
I'm getting compilation error:
Invalid arguments ' Candidates are:
__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>> insert(__gnu_cxx::__normal_iterator<const int
*,std::vector<int,std::allocator<int>>>, const int &)
__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>> insert(__gnu_cxx::__normal_iterator<const int
*,std::vector<int,std::allocator<int>>>, int &&)
__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>> insert(__gnu_cxx::__normal_iterator<const int
*,std::vector<int,std::allocator<int>>>, std::initializer_list<int>)
__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>> insert

Ths code compiles and works without error. Tested with https://wandbox.org/
#include <vector>
#include <iostream>
typedef unsigned long int U64;
int main()
{
std::vector<U64> vectorA = { 3, 4};
std::vector<U64> vectorB = { 5, 7};
vectorA.insert(vectorA.end(), vectorB.begin(), vectorB.end());
for (const auto& i: vectorA)
std::cout << i << ' ';
}
There is something you're not telling us.
Be aware that what is used here is NOT STL. STL is a legacy library that was created in 90s. What we are using now is standard C++ library which is based on STL and boost to extent. STL is still around for historical reasons. But STL doesn't comply to C++ standard. Something is wrong with include paths or with toolchain. It possible that you actually try to compile with vanilla STL headers, or some headers were mixed up with boost headers.

Related

Eigen with -O3 warning: argument 1 value ‘X’ exceeds maximum object size Y

What happens
When I try to add an Eigen::Vector3f into an std::vector following the tutorial on Eigen website like this:
#include <Eigen/Core>
#include <Eigen/StdVector>
#include <iostream>
template <class EigenT>
using EigenStdVector = std::vector<EigenT, Eigen::aligned_allocator<EigenT>>;
int main() {
EigenStdVector<Eigen::Vector3f> vec;
vec.emplace_back(1.0f, 1.0f, 1.0f);
std::cerr << vec.back().transpose() << std::endl;
return 0;
}
I get the following warning:
In file included from /usr/include/eigen3/Eigen/Core:349:0,
from /home/igor/Code/eigen_example/example.cpp:3:
In function ‘void* Eigen::internal::aligned_malloc(std::size_t)’,
inlined from ‘void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {float, float, float}; _Tp = Eigen::Matrix<float, 3, 1>; _Alloc = Eigen::aligned_allocator<Eigen::Matrix<float, 3, 1> >]’ at /usr/include/eigen3/Eigen/src/Core/util/Memory.h:742:76:
/usr/include/eigen3/Eigen/src/Core/util/Memory.h:159:12: warning: argument 1 value ‘18446744073709551612’ exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=]
result = std::malloc(size);
How to reproduce
I am on Ubuntu 18.04 and have Eigen 3.3.4 installed.
You can build the code in this question with the following command if you have Eigen installed with the following command:
g++ -I/usr/include/eigen3 -O3 example.cpp
What triggers the warning
The warning only shows when using Vector2f, Vector3f, etc. It is not shown for types like Matrix2f, Matrix3f, etc.
The warning is shown whenever I have -O[1-3] enabled and does not happen with -O0
Further info:
This question seems to be related, but I don't see how it could help me.
I have made a small example for everyone who wants a ready-to-run example. You can find it on my GitHub.
Does anybody have an idea what might be wrong here?
In the file Eigen/src/Core/util/Memory.h in the implementation of Eigen::aligned_allocator these lines can be found:
#if EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_LEAST(7,0)
// In gcc std::allocator::max_size() is bugged making gcc triggers a warning:
// eigen/Eigen/src/Core/util/Memory.h:189:12: warning: argument 1 value '18446744073709551612' exceeds maximum object size 9223372036854775807
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87544
size_type max_size() const {
return (std::numeric_limits<std::ptrdiff_t>::max)()/sizeof(T);
}
#endif
So, it seems that this is connected to this GCC bug.
As far as I can see, the commit fixing this appeared on 2018-10-07, and should be available in Eigen 3.3.6.

error: call of overloaded distance is ambiguous

I have a bit of code (which I didn't write, but am trying to compile) -- iostream_combo.cc--, and doing so gives me the following error:
./moses/moses/comboreduct/combo/iostream_combo.cc: In function ‘std::__cxx11::string opencog::combo::l2ph(const string&, const std::vector<std::__cxx11::basic_string<char> >&)’:
./moses/moses/comboreduct/combo/iostream_combo.cc:543:64: error: call of overloaded ‘distance(std::vector<std::__cxx11::basic_string<char> >::const_iterator, __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >&)’ is ambiguous
arity_t idx = distance(labels.begin(), found_it) + 1;
^ In file included from /usr/include/c++/8/bits/stl_algobase.h:66,
from /usr/include/c++/8/bits/char_traits.h:39,
from /usr/include/c++/8/ios:40,
from /usr/include/c++/8/ostream:38,
from /usr/include/c++/8/iostream:39,
from ./moses/moses/comboreduct/combo/iostream_combo.h:28,
from ./moses/moses/comboreduct/combo/iostream_combo.cc:24:
/usr/include/c++/8/bits/stl_iterator_base_funcs.h:138:5: note: candidate: ‘typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; typename std::iterator_traits<_Iterator>::difference_type = long int]’
distance(_InputIterator __first, _InputIterator __last)
^~~~~~~~ In file included from /usr/local/include/boost/range/distance.hpp:18,
from /usr/local/include/boost/range/functions.hpp:21,
from /usr/local/include/boost/range/iterator_range_core.hpp:38,
from /usr/local/include/boost/lexical_cast.hpp:30,
from ./moses/moses/comboreduct/combo/iostream_combo.h:30,
from ./moses/moses/comboreduct/combo/iostream_combo.cc:24:
/usr/local/include/boost/iterator/distance.hpp:49:9: note: candidate: ‘constexpr typename boost::iterators::iterator_difference<Iterator>::type boost::iterators::distance_adl_barrier::distance(SinglePassIterator, SinglePassIterator) [with SinglePassIterator = __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; typename boost::iterators::iterator_difference<Iterator>::type = long int]’
distance(SinglePassIterator first, SinglePassIterator last)
^~~~~~~~
I'm using Ubuntu 16.04 x64, Boost 1.68 and gcc 8.2. So, the steps to reproduce the problem would be as follows:
On Ubuntu 16.04
install gcc-8
Use it to build boost 1.68 from source
Git clone the moses repository sand follow the instructions from there: basically 1) git clone and build cogutil; 2) try to make moses:
cd build, cmake .., make.
I understand C++ enough (I think) that I can see that the call to std::distance is overloaded. What I don't see is the way to disambiguate it, although I guess it must include some re-writing of found_it or some explicit castings instead of auto.
The calls are like:
arity_t idx = distance(labels.begin(), found_it) + 1;
This means that distance is found via ADL and hence all associated namespaces are considered. This might prove problematic if e.g. there are two namespaces providing an equally applicable overload for distance:
Live On Coliru
#include <iterator>
#include <vector>
namespace OyVeh {
struct X { };
template <typename It>
size_t distance(It, It) { return 42; } // just to throw in a wrench
}
int main() {
std::vector<OyVeh::X> v{3};
auto f = v.begin();
auto l = v.end();
// now f and l have both `::std` and `::OyVeh` as associated namespaces. The following is ambiguous:
return distance(f, l);
}
There are roughly 2 ways to fix it:
remove the ambigious distance declaration from the associated namespace (this might not be possible if e.g. the ones competing are std::distance and boost::distance)
edit the calls to remove the reliance on ADL (e.g. qualify them like std::distance(...) or parenthesize them (distance)(...))
Showing the workarounds:
Live On Coliru
{
using OyVeh::distance;
return (distance)(f, l); // parentheses suppress ADL
}
return std::distance(f, l); // also works, obviously
return OyVeh::distance(f, l); // but beware the meaning might change

Ambiguous overloading due to Boost headers when compiling C++98 code with C++11 option

Abstract :
My C++98 code uses some boost libraries and some own functions (existing in C++11) defined in a own namspace. It compiles very well with gcc 4.8.x. When I try to compile it with option -std=c++11, I get a call to overloaded xxx is ambiguous error on my own function in my own namespace. This function exists in C++11 in namespace std. It looks like boost calls using namespace std; in a header...
Details :
Consider the following simple code :
#include <vector>
#include <iostream>
#include <boost/math/special_functions/erf.hpp>
namespace caduchon
{
template <typename Iterator>
bool is_sorted(Iterator begin, Iterator end)
{
if(begin == end) return true;
for(Iterator it = begin, prev = it++; it != end; prev = it++)
if(*it < *prev) return false;
return true;
}
}
using namespace caduchon;
int main()
{
std::vector<double> x(3);
x[0] = 10.0; x[1] = 13.9; x[2] = 21.3;
std::cout << "Is x sorted ? " << is_sorted(x.begin(), x.end()) << std::endl;
// Imagine here a call to boost::math::erf(double)
return 0;
}
It compiles very well with gcc 4.8.5 with the following command : g++ test.cpp -o test.exe -I /softs/boost/1.63.0/64/gcc/4.8.5/include
I have an error if I add the option -std=c++11 in the compilation command :
g++ test.cpp -o test.exe -I /softs/boost/1.63.0/64/gcc/4.8.5/include -std=c++11
test.cpp: In function ‘int main()’:
test.cpp:28:61: error: call of overloaded ‘is_sorted(std::vector<double>::iterator, std::vector<double>::iterator)’ is ambiguous
std::cout << "is sorted ? " << is_sorted(x.begin(), x.end()) << std::endl;
^
test.cpp:28:61: note: candidates are:
test.cpp:9:7: note: bool caduchon::is_sorted(Iterator, Iterator) [with Iterator = __gnu_cxx::__normal_iterator<double*, std::vector<double> >]
bool is_sorted(Iterator begin, Iterator end)
^
In file included from /usr/include/c++/4.8/algorithm:62:0,
from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/tools/config.hpp:18,
from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/tools/promotion.hpp:26,
from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/special_functions/detail/round_fwd.hpp:12,
from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/special_functions/math_fwd.hpp:26,
from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/special_functions/erf.hpp:13,
from test.cpp:3:
/usr/include/c++/4.8/bits/stl_algo.h:3952:5: note: bool std::is_sorted(_FIter, _FIter) [with _FIter = __gnu_cxx::__normal_iterator<double*, std::vector<double> >]
is_sorted(_ForwardIterator __first, _ForwardIterator __last)
I don't have the error if I remove the inclusion for boost::math::erf function.
I don't have the error if I replace is_sorted by caduchon::is_sorted (but I don't want to impact all my code).
It realy looks like a header of boost calls using namespace std; when option -std=c++11 is defined.
Why ? In my opinion, it's a very bad practice to call using namespace ...; in a header... Is it a bug ?
Is there a simple solution not intrusive for my code ?
Note : I have to compile with option -std=c++11 to be able to use Boost.Process (from Boost 1.64) in a specific module of my code, for a specific platform, with specific compilation flags. The rest of the code must compile under old gcc (4.4.x).
Argument-dependent_name_lookup (ADL) in action:
x.begin() return type is std::vector<double>::iterator.
if it belongs to std namespace, then
is_sorted(x.begin(), x.end())
is look up in namespace std too.
Boost might add some include (<algorithm>) conditionally to support c++11 features in its header.
That happens without any using namespace std;

std::sort with local type Compare

The following example
// file mysort.cc
#include <string>
#include <vector>
#include <algorithm>
#include <string.h>
void mysort (const char**tab, unsigned size) {
std::vector<int> vecix;
vecix.resize(size);
struct CompareIndex {
const char**t;
CompareIndex(const char**p) : t(p) {};
bool operator() (int l, int r) {
return strcmp(t[l], t[r])<0;
}
};
CompareIndex compix(tab);
for (unsigned ix=0; ix<size; ix++) vecix[ix] = ix;
std::stable_sort(vecix.begin(), vecix.end(), compix);
std::vector<const char*> vecstr;
vecstr.resize(size);
for (unsigned ix=0; ix<size; ix++) vecstr[ix] = tab[vecix[ix]];
for (unsigned ix=0; ix<size; ix++) tab[ix] = vecstr[ix];
}
fails to compile (using GCC 4.8.2 on Debian/Sid/x86-64 in C++03 standard)
mysort.cc: In function 'void mysort(const char**, unsigned int)':
mysort.cc:19:58: error: no matching function for call to
'stable_sort(std::vector<int>::iterator,
std::vector<int>::iterator,
mysort(const char**, unsigned int)::CompareIndex&)'
std::stable_sort(vecix.begin(), vecix.end(), compix);
^
In file included from /usr/include/c++/4.8/algorithm:62:0,
from mysort.cc:4:
/usr/include/c++/4.8/bits/stl_algo.h:5682:5: note:
template<class _RAIter, class _Compare>
void std::stable_sort(_RAIter, _RAIter, _Compare)
stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
/usr/include/c++/4.8/bits/stl_algo.h:5682:5: note:
template argument deduction/substitution failed:
mysort.cc: In substitution of 'template<class _RAIter, class _Compare>
void std::stable_sort(_RAIter, _RAIter, _Compare)
[with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >;
_Compare = mysort(const char**, unsigned int)::CompareIndex]':
mysort.cc:19:58: required from here
mysort.cc:19:58: error: template argument for
'template<class _RAIter, class _Compare>
void std::stable_sort(_RAIter, _RAIter, _Compare)'
uses local type 'mysort(const char**, unsigned int)::CompareIndex'
std::stable_sort(vecix.begin(), vecix.end(), compix);
^
mysort.cc:19:58: error: trying to instantiate
'template<class _RAIter, class _Compare>
void std::stable_sort(_RAIter, _RAIter, _Compare)'
The above was compiled with GCC 4.8 using
g++ -Wall -c mysort.cc
I am getting the same error with
g++ -std=c++03 -Wall -c mysort.cc
or with
g++ -std=c++98 -Wall -c mysort.cc
but no errors with
g++ -std=c++11 -c mysort.cc
given that my g++ -v is a gcc version 4.8.2 (Debian 4.8.2-12)
but with Clang/LLVM 3.4 compiling with
clang++ -Wall -c mysort.cc
I'm getting only a warning:
mysort.cc:19:7: warning: template argument uses local
type 'CompareIndex'
[-Wlocal-type-template-args]
std::stable_sort(vecix.begin(), vecix.end(), compix);
^~~
1 warning generated.
(and I still get only a warning not an error when passing -std=c++03 or -std=c++98 to clang++ but no warnings with clang++ -std=c++11)
so my question is: why the error by GCC and the warning by Clang? Is my code legal and without undefined behavior (w.r.t. the C++03 standard)? Should I make my CompareIndex a global struct in my compilation unit?
motivations
Of course, this is a silly way to sort an array of C strings.
The real code is a bit different. In fact, I am trying to use std::stable_sort in my MELT plugin (a domain specific language to extend and customize GCC). MELT is generating C++ code and has a copying garbage collector (so pointers are moved by the GC). Hence, I need to sort using an array of indexes: the compare function in fact calls a MELT closure (which could trigger the copying GC at arbitrary moment), so I need to sort by indexes (and not by raw pointers). I want to keep the C++ code generated by MELT conforming to the C++ standard (03 or 98) required to compile GCC.
work-around
Thanks to juanchopanza's answer I've solved the issue by moving the declaration of CompareIndex at global scope before mysort.
I just committed the svn revision 206748 of the MELT branch of GCC; its file gcc/melt/warmelt-base.melt contains now a multiple_sort_new MELT function (to replace multiple_sort when it is working well) using std::stable_sort, and a global Melt_Sort_Compare_Index class in the generated C++ code.
Using local types as template arguments is not allowed in C++03.
From ISO/IEC 14882, 14.3.1 Template type arguments [temp.arg.type]:
A local type, a type with no linkage, an unnamed type or a type
compounded from any of these types shall not be used as a
template-argument for a template type-parameter.
The example given is along these lines:
template <typename T> struct Foo {};
void foo()
{
struct Bar {};
Foo<Bar> b1; // error: local type used as template-argument
Foo<Bar*> x4; // error: pointer to local type used as template-argument
}
This restriction has been lifted in C++11.

make_shared create std::shared_ptr? gcc 4.6.2

i'm using gcc 4.6.2.
I'm trying to push_back in a vector shared_ptr's.
But gcc gives me everytime an error.
Here my codelines:
std::vector< std::tr1::shared_ptr<Process> > procs;
std::string line;
while (getline(file, line) && line.find(JobMask) != std::string::npos)
{
std::string procName = line.substr(line.find(JobMask) + JobMask.size());
std::vector<Instruction> procInstructions = extractProgram(file);
std::queue<int> procInputs = extractInputs(file);
if (!procInstructions.empty())
procs.push_back(std::make_shared<Process>(Process(procName, procInputs, procInstructions))); //line 51
}
return procs;
The Error my gcc is giving is:
Process.cpp: In static member function 'static std::vector<std::tr1::shared_ptr<RMMIX::Process> > RMMIX::Process::createProcesses(const string&)':
Process.cpp:51:95: error: no matching function for call to 'std::vector<std::tr1::shared_ptr<RMMIX::Process> >::push_back(std::shared_ptr<RMMIX::Process>)'
Process.cpp:51:95: note: candidates are:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::tr1::shared_ptr<RMMIX::Process>, _Alloc = std::allocator<std::tr1::shared_ptr<RMMIX::Process> >, std::vector<_Tp, _Alloc>::value_type = std::tr1::shared_ptr<RMMIX::Process>]
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:826:7: note: no known conversion for argument 1 from 'std::shared_ptr<RMMIX::Process>' to 'const value_type& {aka const std::tr1::shared_ptr<RMMIX::Process>&}'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:839:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::tr1::shared_ptr<RMMIX::Process>, _Alloc = std::allocator<std::tr1::shared_ptr<RMMIX::Process> >, std::vector<_Tp, _Alloc>::value_type = std::tr1::shared_ptr<RMMIX::Process>]
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:839:7: note: no known conversion for argument 1 from 'std::shared_ptr<RMMIX::Process>' to 'std::vector<std::tr1::shared_ptr<RMMIX::Process> >::value_type&& {aka std::tr1::shared_ptr<RMMIX::Process>&&}'
In my eyes the error say's, that std::make_shared create a std::shared_ptr.
But in gcc shared_ptr is in the namespace std::tr1.
How could i fix it?
If I understand correctly, make_shared is new in C++11 and is in namespace std, but it is only available if you compile with -std=gnu++0x or similar. But if you do that, then shared_ptr is also in std.
The problem is that there is another version of shared_ptr in std::tr1, but in C++11 mode you should not use it: it should be considered deprecated.
Your solution is simply to remove every use of tr1 and use the full C++11 version of these classes.
C++ template error message can be a beast to read. But the answer is in the 2nd note.
no known conversion for argument 1 from 'std::shared_ptr<RMMIX::Process>' to 'const value_type& {aka const std::tr1::shared_ptr<RMMIX::Process>&}'
The problem is you're using std::make_shared (which creates a std::shared_ptr) and passing it into a vector of std::tr1::shared_ptr.
The simplest solution is drop the TR1. The stuff from the TR1 was some of first features implemented by compilers when adding C++11 support.
std::vector< std::shared_ptr<Process> > procs;
If you are unable to stop using std::tr1::shared_ptr. You'll have to forgo using make_shared as it was not part of the TR1.