I am trying to use the Library Eigen in a project and I have to sort a vector. I tried to follow the documentation and it says that the library should work in the predictable way with the STL iterators and algorithms https://eigen.tuxfamily.org/dox-devel/group__TutorialSTL.html.
However when I try to run the following test code
#include <iostream>
#include <algorithm>
#include <eigen3/Eigen/Dense>
#include <eigen3/Eigen/Core>
int main()
{
Eigen::Array4i v = Eigen::Array4i::Random().abs();
std::cout << "Here is the initial vector v:\n" << v.transpose() << "\n";
std::sort(v.begin(), v.end());
std::cout << "Here is the sorted vector v:\n" << v.transpose() << "\n";
return 0;
}
I get the two following errors:
error: ‘Eigen::Array4i’ {aka ‘class Eigen::Array<int, 4, 1>’} has no member named ‘begin’
9 | std::sort(v.begin(), v.end());
| ^~~~~
error: ‘Eigen::Array4i’ {aka ‘class Eigen::Array<int, 4, 1>’} has no member named ‘end’
9 | std::sort(v.begin(), v.end());
I tested it with gcc 9.1.0 and 7.4.0 and my version of Eigen is 3.3.4. I am using Ubuntu 18.04 and the library is in the usual location /usr/include. All the other functionality I tried seem to work properly.
Is it a well known bug, is it a compiler problem or is it a version problem?
If you don't want to wait for the release of Eigen 3.4, you can use this:
std::sort(v.data(), v.data() + v.size());
The .data() method can replace the missing .begin(), but the .end() method must be constructed manually.
Related
I'm new to c++ and have taken the liberty to learn it this summer after coming from a python background. I was watching a video about how to create and use tuples within c++ and it seemed to have worked for the YouTuber, however when I replicated his steps, my compiler had thrown some errors even though there was no distinct differences in the code
code:
#include <iostream>
#include <string>
#include <tuple>
int main() {
std::tuple <int, std::string> person(18, "Chris");
std::cout << std::get<1>(person) << std::endl;
return 0;
}
Errors:
❯ g++ -o main Tuples.cpp && ./main
Tuples.cpp:7:10: error: no member named 'tuple' in namespace 'std'
std::tuple <int, std::string> person(18, "Chris");
~~~~~^
Tuples.cpp:7:20: error: expected '(' for function-style cast or type construction
std::tuple <int, std::string> person(18, "Chris");
~~~^
Tuples.cpp:8:30: error: use of undeclared identifier 'person'
std::cout << std::get<1>(person) << std::endl;
^
3 errors generated.
Video for reference: https://www.youtube.com/watch?v=T9-agjKW4PQ&list=PLzMcBGfZo4-lmGC8VW0iu6qfMHjy7gLQ3&index=16
This question already has an answer here:
Why is std::back_inserter_iterator not WeaklyIncrementable in RangeV3?
(1 answer)
Closed 2 years ago.
I am building some snippets that should work with both the C++20 Ranges library and the range-v3 library and I noticed some differences in the implementation of the copy algorithm.
The following code using C++20 ranges library (from the Standard Library), compiles with GCC 11 (and prints 1 2 3 4 5).
#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
int main()
{
std::vector<int> arr {1, 2, 3, 4, 5};
std::ranges::copy(arr, std::ostream_iterator<int>(std::cout, " "));
}
Here is a link: https://wandbox.org/permlink/V13bdDoxSYjqDW3m
The same code, using the range-v3 library, fails to compile with VC++ 2019 16.5:
#include <iostream>
#include <vector>
#include "range/v3/algorithm/copy.hpp"
int main()
{
std::vector<int> arr {1, 2, 3, 4, 5};
ranges::copy(arr, std::ostream_iterator<int>(std::cout, " "));
}
With the following errors:
main.cpp(134,9): error C2672: 'operator __surrogate_func': no matching overloaded function found
main.cpp(134,59): error C7602: 'ranges::_copy::copy_fn::operator ()': the associated constraints are not satisfied
range-v3-master\include\range/v3/algorithm/copy.hpp(57): message : see declaration of 'ranges::_copy::copy_fn::operator ()'
main.cpp(134,59): error C2780: 'ranges::detail::in_out_result<I,O> ranges::_copy::copy_fn::operator ()(I,S,O) const': expects 3 arguments - 2 provided
range-v3-master\include\range/v3/algorithm/copy.hpp(45): message : see declaration of 'ranges::_copy::copy_fn::operator ()'
There is a unit test in the range-v3 library, which is very similar:
using namespace ranges;
std::ostringstream sout;
std::vector<int> copy_vec{1,1,1,1,1};
copy(copy_vec, ostream_iterator<>(sout, " "));
CHECK(sout.str() == "1 1 1 1 1 ");
If I try is with Compiler Explorer, it does not compile with any compiler (gcc, Clang, VC++). The gcc errors are:
note: candidate expects 1 argument, 2 provided
note: candidate expects 3 arguments, 2 provided
error: no match for call to '(const ranges::copy_fn) (std::vector<int>&, std::ostream_iterator<int>)'
required from here
These are basically the same errors that I see in VC++ for my snippet.
Here is a link: https://godbolt.org/z/pEfBb4
I would expect these two would work interchangeably. Why is it no so?
Just to clarify for others looking at the question:
The unit test work because its ranges::ostream_iterator and not std::ostream_iterator that is used in that snippet.
The std::ostream_iterator does not work because it doesn't satisfy the range Iterator concept since it's not default constructible.
I'm getting an unexpectred error when I initialize a vector in the main.
I was expecting the following output:
0 1 2
I can't see why it's not working. I also writed the same code in another pc using the same compiler, and it works.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vett = {0,1,2};
for (int i : vett) {
cout << i << " ";
}
return 0;
}
error: could not convert '{0, 1, 2}' from '<brace-enclosed initializer list>' to 'std::vector<int>'|
You need to compile with at least C++11. List initialization came with C++11.
-std=c++11
You are compiling with something older than C++11, it does not support initializer list constructor.
If you are using Code::Blocks follow these steps:
Settings -> compiler -> compiler flags -> select C++11 or above
I'm trying to compile a c++ program which uses std::make_reverse_iterator, but I get the title error. The reference says that the function is indeed supported since c++14, so I added the flag -std=c++14, but still no dice. I've been digging around for a while and can't figure out why this is happening. Any ideas? My compiler version is g++ 4.9.2
Here's a simple program (taken from the above ref), the commands used to compile it, and the program's output.
test.cpp:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
int main() {
auto v = std::vector<int>{ 1, 3, 10, 8, 22 };
std::sort(v.begin(), v.end());
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, ", "));
std::cout << '\n';
std::copy(
std::make_reverse_iterator(v.end()),
std::make_reverse_iterator(v.begin()),
std::ostream_iterator<int>(std::cout, ", "));
}
Compiler:
g++ -std=c++14 test.cpp -o test
Output:
test.cpp: In function ‘int main()’:
test.cpp:15:9: error: ‘make_reverse_iterator’ is not a member of ‘std’
std::make_reverse_iterator(v.end()),
^
test.cpp:16:9: error: ‘make_reverse_iterator’ is not a member of ‘std’
std::make_reverse_iterator(v.begin()),
make_reverse_iterator() was added as a result of LWG 2285 and wasn't added to libsdtc++ until December 2014. It's in 5.1 release, and everything there. 4.9.2 was just too early to have it. So if possible, just upgrade.
If not possible, this is something that you can add yourself by just copying the cppreference implementation:
template< class Iterator >
std::reverse_iterator<Iterator> make_reverse_iterator(Iterator i)
{
return std::reverse_iterator<Iterator>(i);
}
I am currently trying to get the following very simple boost::phoenix::lambda to compile:
#include <iostream>
#include <boost/phoenix/scope.hpp>
int main() {
boost::phoenix::lambda[std::cout << "Lambda!!"]();
}
However, this generates a host of errors (too much to post here), none which make any sense to me. Here is an excerpt of the compiler output:
error: 'std::ios_base::ios_base(const std::ios_base&)' is private
within this context
error: initializer for
'boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<boost::phoenix::vector0<> >, 0l>::proto_child0
{aka boost::phoenix::vector0<>}' must be brace-enclosed
I am compiling these using MinGW 4.7.2 on Windows XP with Boost 1.53.0. What am I doing wrong?
Firstly, always
#include <boost/phoenix/phoenix.hpp>
unless you know what you're doing.
Secondly, you need to make either operand of operator<< be a phoenix terminal, otherwise, it will be just
std::cout << "Lambda!!"
which is an expression of type std::ostream&...
Now, you could do anything, really, e.g.
phx::ref(std::cout) << "Lambda!!"
or
std::cout << phx::val("Lambda!!")
Either will compile.