C++ std::find comparing a pointer to a reference - c++11

I am attempting to make a simple Graph system.
(I'm calling my nodes "Cells", but they're just basically nodes)
Here's my header:
class Cell {
public:
virtual ~Cell() {}
Cell(int row, int column);
std::tuple<int, int> getCoord() const;
void link(Cell& adjacent, bool biDirectional = true);
void unlink(Cell& adjacent, bool biDirectional = true);
friend std::ostream& operator<<(std::ostream& out, const Cell& cell);
bool operator==(const Cell& other) const;
private:
bool isLinked(const Cell& cell) const;
int mRow, mColumn;
std::vector<Cell*> links;
};
As you can see, I'm overloading the equivalency operator so I can compare cells by their coordinates. Here's the relevant methods in my .cpp file:
bool Cell::operator==(const Cell& other) const {
return mRow == other.mRow && mColumn == other.mColumn;
}
bool Cell::isLinked(const Cell& cell) const {
return std::end(links) ==
std::find(std::begin(links), std::end(links),
[cell](Cell* cellPtr) { return (*cellPtr) == cell; });
}
As you can see, when I want to compare equivalency I check to see if the x,y coordinates are the same. In my Cell::isLinked method, I take the std::vector<Cell*> linksand pass them to std::find which then takes the object at the ptr and should then compare it (using the overloaded comparison operator from earlier) and return true or false.
Instead I'm getting this error when I try to build my project:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:865:22: error:
invalid operands to binary expression ('Cell *' and 'const (lambda at Cell.cpp:51:20)')
if (*__first == __value_)
~~~~~~~~ ^ ~~~~~~~~
Cell.cpp:50:15: note: in instantiation of function template specialization
'std::__1::find<std::__1::__wrap_iter<Cell *const *>, (lambda at Cell.cpp:51:20)>' requested here
std::find(std::begin(links), std::end(links),

Related

C++ multiset error C2676: binary '-': 'const _BidIt' does not define this operator or a conversion to a type acceptable to the predefined operator

I have the following C++ classes:
class MyClass {
private:
int _id;
unsigned long long _timestamp;
public:
MyClass(int id, unsigned long long ts) : _id(id), _timestamp(ts) {}
bool operator<(const MyClass& other) const { return _timestamp < other._timestamp; }
int GetID() {return _id;}
};
class MyClass1 {
private:
map<int, multiset<MyClass>> _list;
public:
vector<int> GetMyClasses(int id, int count) {
vector<int> result;
transform(_list[id].rbegin(), _list[id].rbegin() + count, back_inserter(result), [](const MyClass& c) {return c.GetID();});
return result;
}
};
This is the build error:
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\include\xutility(1915,41): error C2676: binary '-': 'const _BidIt' does not define this operator or a conversion to a type acceptable to the predefined operator
I am using VS2019 Version 16.7.7. Any insight and advice is appreciated.
You cannot increment an iterator of multiset by simple +.
Use std::advance to do it:
auto it = _list[id].rbegin();
auto it2 = it;
std::advance(it2,count);
transform(it, it2,
back_inserter(result), [](const MyClass& c) {return c.GetID();});
also GetID must be const method.
Demo

Passing const reference pointer fails to match method signature

The following code passes a const pointer reference to a size() helper function. It only works if I remove the const or the & reference operator from the helper function.
#include <iostream>
using namespace std;
template <typename T>
class Test {
public:
Test();
int size();
void insert(T);
private:
struct Node {
T value;
Node* left;
Node* right;
};
Node* root;
int size(const Node*& node);
};
template <typename T>
Test<T>::Test() { root = nullptr;}
template <typename T>
int Test<T>::size() {return size(root);}
template <typename T>
int Test<T>::size(const Node*& node) {
if (node != nullptr)
return 1 + size(node->left) + size(node->right);
return 0;
}
int main() {
Test<int> t;
cout << "Size: " << t.size() << endl;
}
I get the following compiler errors when I compile this code as C++11:
main.cpp:31:11: error: no matching member function for call to 'size'
return size(root);
^~~~
main.cpp:43:26: note: in instantiation of member function 'Test<int>::size' requested here
cout << "Size: " << t.size() << endl;
^
main.cpp:21:11: note: candidate function not viable: no known conversion from 'Test<int>::Node *' to 'const Test<int>::Node *&' for 1st argument
int size(const Node*& node);
^
main.cpp:10:11: note: candidate function not viable: requires 0 arguments, but 1 was provided
int size();
^
1 error generated.
However, if I simply remove the const or the reference operator (&) from the helper function that size() calls, it compiles and runs exactly as expected.
In other words, either of the following works:
int size(Node*& node);
template <typename T> int Test<T>::size(Node*& node)
int size(const Node* node);
template <typename T> int Test<T>::size(const Node* node)
But this does not:
int size(const Node*& node);
template <typename T> int Test<T>::size(const Node*& node)
The declaration and implementation seem identical in all three cases, so I am having a hard time figuring out why the case with the const reference fails.
If it were legal to pass a pointer to non-const object where a reference to pointer to const object is expected, then it would be possible to violate const correctness. Consider:
const int c = 42;
void f(const int*& p) {
// Make p point to c
p = &c;
}
int* q;
f(q); // hypothetical, doesn't compile
// Now q points to c
*q = 84; // oops, modifying a const object

Persistent expression templates with unique_ptr and matrices

I want to use expression templates to create a tree of objects that persists across statement. Building the tree initially involves some computations with the Eigen linear algebra library. The persistent expression template will have additional methods to compute other quantities by traversing the tree in different ways (but I'm not there yet).
To avoid problems with temporaries going out of scope, subexpression objects are managed through std::unique_ptr. As the expression tree is built, the pointers should be propagated upwards so that holding the pointer for the root object ensures all objects are kept alive. The situation is complicated by the fact that Eigen creates expression templates holding references to temporaries that go out of scope at the end of the statement, so all Eigen expressions must be evaluated while the tree is being constructed.
Below is a scaled-down implementation that seems to work when the val type is an object holding an integer, but with the Matrix type it crashes while constructing the output_xpr object. The reason for the crash seems to be that Eigen's matrix product expression template (Eigen::GeneralProduct) gets corrupted before it is used. However, none of the destructors either of my own expression objects or of GeneralProduct seems to get called before the crash happens, and valgrind doesn't detect any invalid memory accesses.
Any help will be much appreciated! I'd also appreciate comments on my use of move constructors together with static inheritance, maybe the problem is there somewhere.
#include <iostream>
#include <memory>
#include <Eigen/Core>
typedef Eigen::MatrixXi val;
// expression_ptr and derived_ptr: contain unique pointers
// to the actual expression objects
template<class Derived>
struct expression_ptr {
Derived &&transfer_cast() && {
return std::move(static_cast<Derived &&>(*this));
}
};
template<class A>
struct derived_ptr : public expression_ptr<derived_ptr<A>> {
derived_ptr(std::unique_ptr<A> &&p) : ptr_(std::move(p)) {}
derived_ptr(derived_ptr<A> &&o) : ptr_(std::move(o.ptr_)) {}
auto operator()() const {
return (*ptr_)();
}
private:
std::unique_ptr<A> ptr_;
};
// value_xpr, product_xpr and output_xpr: expression templates
// doing the actual work
template<class A>
struct value_xpr {
value_xpr(const A &v) : value_(v) {}
const A &operator()() const {
return value_;
}
private:
const A &value_;
};
template<class A,class B>
struct product_xpr {
product_xpr(expression_ptr<derived_ptr<A>> &&a, expression_ptr<derived_ptr<B>> &&b) :
a_(std::move(a).transfer_cast()), b_(std::move(b).transfer_cast()) {
}
auto operator()() const {
return a_() * b_();
}
private:
derived_ptr<A> a_;
derived_ptr<B> b_;
};
// Top-level expression with a matrix to hold the completely
// evaluated output of the Eigen calculations
template<class A>
struct output_xpr {
output_xpr(expression_ptr<derived_ptr<A>> &&a) :
a_(std::move(a).transfer_cast()), result_(a_()) {}
const val &operator()() const {
return result_;
}
private:
derived_ptr<A> a_;
val result_;
};
// helper functions to create the expressions
template<class A>
derived_ptr<value_xpr<A>> input(const A &a) {
return derived_ptr<value_xpr<A>>(std::make_unique<value_xpr<A>>(a));
}
template<class A,class B>
derived_ptr<product_xpr<A,B>> operator*(expression_ptr<derived_ptr<A>> &&a, expression_ptr<derived_ptr<B>> &&b) {
return derived_ptr<product_xpr<A,B>>(std::make_unique<product_xpr<A,B>>(std::move(a).transfer_cast(), std::move(b).transfer_cast()));
}
template<class A>
derived_ptr<output_xpr<A>> eval(expression_ptr<derived_ptr<A>> &&a) {
return derived_ptr<output_xpr<A>>(std::make_unique<output_xpr<A>>(std::move(a).transfer_cast()));
}
int main() {
Eigen::MatrixXi mat(2, 2);
mat << 1, 1, 0, 1;
val one(mat), two(mat);
auto xpr = eval(input(one) * input(two));
std::cout << xpr() << std::endl;
return 0;
}
Your problem appears to be that you are using someone else's expression templates, and storing the result in an auto.
(This happens in product_xpr<A>::operator(), where you call *, which if I read it right, is an Eigen multiplication that uses expression templates).
Expression templates are often designed to presume the entire expression will occur on a single line, and it will end with a sink type (like a matrix) that causes the expression template to be evaluated.
In your case, you have a*b expression template, which is then used to construct an expression template return value, which you later evaluate. The lifetime of temporaries passed to * in a*b are going to be over by the time you reach the sink type (matrix), which violates what the expression templates expect.
I am struggling to come up with a solution to ensure that all temporary objects have their lifetime extended. One thought I had was some kind of continuation passing style, where instead of calling:
Matrix m = (a*b);
you do
auto x = { do (a*b) pass that to (cast to matrix) }
replace
auto operator()() const {
return a_() * b_();
}
with
template<class F>
auto operator()(F&& f) const {
return std::forward<F>(f)(a_() * b_());
}
where the "next step' is passed to each sub-expression. This gets trickier with binary expressions, in that you have to ensure that the evaluation of the first expression calls code that causes the second sub expression to be evaluated, and then the two expressions are combined, all in the same long recursive call stack.
I am not proficient enough in continuation passing style to untangle this knot completely, but it is somewhat popular in the functional programming world.
Another approach would be to flatten your tree into a tuple of optionals, then construct each optional in the tree using a fancy operator(), and manually hook up the arguments that way. Basically do manual memory management of the intermediate values. This will work if the Eigen expression templates are either move-aware or do not have any self-pointers, so that moving at the point of construction doesn't break things. Writing that would be challenging.
Continuation passing style, suggested by Yakk, solves the problem and isn't too insane (not more insane than template metaprogramming in general anyhow). The double lambda evaluation for the arguments of binary expressions can be tucked away in a helper function, see binary_cont in the code below. For reference, and since it's not entirely trivial, I'm posting the fixed code here.
If somebody understands why I had to put a const qualifier on the F type in binary_cont, please let me know.
#include <iostream>
#include <memory>
#include <Eigen/Core>
typedef Eigen::MatrixXi val;
// expression_ptr and derived_ptr: contain unique pointers
// to the actual expression objects
template<class Derived>
struct expression_ptr {
Derived &&transfer_cast() && {
return std::move(static_cast<Derived &&>(*this));
}
};
template<class A>
struct derived_ptr : public expression_ptr<derived_ptr<A>> {
derived_ptr(std::unique_ptr<A> &&p) : ptr_(std::move(p)) {}
derived_ptr(derived_ptr<A> &&o) = default;
auto operator()() const {
return (*ptr_)();
}
template<class F>
auto operator()(F &&f) const {
return (*ptr_)(std::forward<F>(f));
}
private:
std::unique_ptr<A> ptr_;
};
template<class A,class B,class F>
auto binary_cont(const derived_ptr<A> &a_, const derived_ptr<B> &b_, const F &&f) {
return a_([&b_, f = std::forward<const F>(f)] (auto &&a) {
return b_([a = std::forward<decltype(a)>(a), f = std::forward<const F>(f)] (auto &&b) {
return std::forward<const F>(f)(std::forward<decltype(a)>(a), std::forward<decltype(b)>(b));
});
});
}
// value_xpr, product_xpr and output_xpr: expression templates
// doing the actual work
template<class A>
struct value_xpr {
value_xpr(const A &v) : value_(v) {}
template<class F>
auto operator()(F &&f) const {
return std::forward<F>(f)(value_);
}
private:
const A &value_;
};
template<class A,class B>
struct product_xpr {
product_xpr(expression_ptr<derived_ptr<A>> &&a, expression_ptr<derived_ptr<B>> &&b) :
a_(std::move(a).transfer_cast()), b_(std::move(b).transfer_cast()) {
}
template<class F>
auto operator()(F &&f) const {
return binary_cont(a_, b_,
[f = std::forward<F>(f)] (auto &&a, auto &&b) {
return f(std::forward<decltype(a)>(a) * std::forward<decltype(b)>(b));
});
}
private:
derived_ptr<A> a_;
derived_ptr<B> b_;
};
template<class A>
struct output_xpr {
output_xpr(expression_ptr<derived_ptr<A>> &&a) :
a_(std::move(a).transfer_cast()) {
a_([this] (auto &&x) { this->result_ = x; });
}
const val &operator()() const {
return result_;
}
private:
derived_ptr<A> a_;
val result_;
};
// helper functions to create the expressions
template<class A>
derived_ptr<value_xpr<A>> input(const A &a) {
return derived_ptr<value_xpr<A>>(std::make_unique<value_xpr<A>>(a));
}
template<class A,class B>
derived_ptr<product_xpr<A,B>> operator*(expression_ptr<derived_ptr<A>> &&a, expression_ptr<derived_ptr<B>> &&b) {
return derived_ptr<product_xpr<A,B>>(std::make_unique<product_xpr<A,B>>(std::move(a).transfer_cast(), std::move(b).transfer_cast()));
}
template<class A>
derived_ptr<output_xpr<A>> eval(expression_ptr<derived_ptr<A>> &&a) {
return derived_ptr<output_xpr<A>>(std::make_unique<output_xpr<A>>(std::move(a).transfer_cast()));
}
int main() {
Eigen::MatrixXi mat(2, 2);
mat << 1, 1, 0, 1;
val one(mat), two(mat), three(mat);
auto xpr = eval(input(one) * input(two) * input(one) * input(two));
std::cout << xpr() << std::endl;
return 0;
}

Standard method for determining the arity and other traits of std::bind() result?

I've been pounding my head for a few days trying to figure out how to make a class have a nice clean public interface to perform registration of callback mechanisms. The callbacks can be C++11 lambdas, std::function<void(Type1,Type2)>, std::function<void(Type2)>, std::function<void()>, or the results of std::bind().
The key to this interface is that the user of the class only needs to know about one public interface that accepts pretty much any functor/callback mechanism the user might throw at it.
Simplified class showing registration of functors and interface
struct Type1;
struct Type2; // May be the same type as Type1
class MyRegistrationClass
{
public:
/**
* Clean and easy to understand public interface:
* Handle registration of any functor matching _any_ of the following
* std::function<void(Type1,Type2)>
* std::function<void(Type2)> <-- move argument 2 into arg 1
* std::function<void()>
* or any result of std::bind() requiring two or fewer arguments that
* can convert to the above std::function< ... > types.
*/
template<typename F>
void Register(F f) {
doRegister(f);
}
private:
std::list< std::function< void(Type1, Type2) > > callbacks;
// Handle registration for std::function<void(Type1,Type2)>
template <typename Functor>
void doRegister(const Functor & functor,
typename std::enable_if<
!is_bind_expr<Functor>
&& functor_traits<decltype(&Functor::operator())>::arity == 2
>::type * = nullptr )
{
callbacks.push_back( functor );
}
// Handle registration for std::function<void(Type2)> by using std::bind
// to discard argument 2 ...
template <typename Functor>
void doRegister(const Functor & functor,
typename std::enable_if<
!std::is_bind_expression< Functor >::value
&& functor_traits<decltype(&Functor::operator())>::arity == 1
>::type * = nullptr )
{
// bind _2 into functor
callbacks.push_back( std::bind( functor, std::placeholders::_2 ) );
}
// Handle registration for std::function<void(Type2)> if given the results
// of std::bind()
template <typename Functor>
void doRegister(const Functor & functor,
typename std::enable_if<
is_bind_expr<Functor>
///////////////////////////////////////////////////////////////////////////
//// BEGIN Need arity of a bounded argument
///////////////////////////////////////////////////////////////////////////
&& functor_traits<decltype(Functor)>::arity == 1
///////////////////////////////////////////////////////////////////////////
//// END need arity of a bounded argument
///////////////////////////////////////////////////////////////////////////
>::type * = nullptr )
{
// Push the result of a bind() that takes a signature of void(Type2)
// and push it into the callback list, it will automatically discard
// argument1 when called, since we didn't bind _1 placeholder
callbacks.push_back( functor );
}
// And other "doRegister" methods exist in this class to handle the other
// types I want to support ...
}; // end class
The only reason to have the complexity of using enable_if<> is to turn on/off certain methods. We have to do this because when we want to pass in the results of std::bind() to the Register() method and it can ambiguously match against multiple registration methods if we had simple signatures like this:
void doRegister( std::function< void(Type1, Type2) > arg );
void doRegister( std::function< void(Type2) > arg ); // NOTE: type2 is first arg
void doRegister( std::function< void() > arg );
Rather than re-invent the wheel, I've referenced traits.hpp and then wrapped it with my own trait helper named "functor_traits" that adds support for std::bind()
This is what I've come up with so far to identify bounded function "arity" ... or a count of how many arguments the bind result expects as a :
My attempt at finding the bind result arity
#include <stdio.h>
// Get traits.hpp here: https://github.com/kennytm/utils/blob/master/traits.hpp
#include "traits.hpp"
using namespace utils;
using namespace std;
void f1() {};
int f2(int) { return 0; }
char f3(int,int) { return 0; }
struct obj_func0
{
void operator()() {};
};
struct obj_func1
{
int operator()(int) { return 0; };
};
struct obj_func2
{
char operator()(int,int) { return 0; };
};
/**
* Count the number of bind placeholders in a variadic list
*/
template <typename ...Args>
struct get_placeholder_count
{
static const int value = 0;
};
template <typename T, typename ...Args >
struct get_placeholder_count<T, Args...>
{
static const int value = get_placeholder_count< Args... >::value + !!std::is_placeholder<T>::value;
};
/**
* get_bind_arity<T> provides the number of arguments
* that a bounded expression expects to have passed in.
*
* This value is get_bind_arity<T>::arity
*/
template<typename T, typename ...Args>
struct get_bind_traits;
template<typename T, typename ...Args>
struct get_bind_traits< T(Args...) >
{
static const int arity = get_placeholder_count<Args...>::value;
static const int total_args = sizeof...(Args);
static const int bounded_args = (total_args - arity);
};
template<template<typename, typename ...> class X, typename T, typename ...Args>
struct get_bind_traits<X<T, Args...>>
{
// how many arguments were left unbounded by bind
static const int arity = get_bind_traits< T, Args... >::arity;
// total arguments on function being called by bind
static const int total_args = get_bind_traits< T, Args... >::total_args;
// how many arguments are bounded by bind:
static const int bounded_args = (total_args - arity);
// todo: add other traits (return type, args as tuple, etc
};
/**
* Define wrapper "functor_traits" that wraps around existing function_traits
*/
template <typename T, typename Enable = void >
struct functor_traits;
// Use existing function_traits library (traits.hpp)
template <typename T>
struct functor_traits<T, typename enable_if< !is_bind_expression< T >::value >::type > :
public function_traits<T>
{};
template <typename T>
struct functor_traits<T, typename enable_if< is_bind_expression< T >::value >::type >
{
static const int arity = get_bind_traits<T>::arity;
};
/**
* Proof of concept and test routine
*/
int main()
{
auto lambda0 = [] {};
auto lambda1 = [](int) -> int { return 0; };
auto lambda2 = [](int,int) -> char { return 0;};
auto func0 = std::function<void()>();
auto func1 = std::function<int(int)>();
auto func2 = std::function<char(int,int)>();
auto oper0 = obj_func0();
auto oper1 = obj_func1();
auto oper2 = obj_func2();
auto bind0 = bind(&f1);
auto bind1 = bind(&f2, placeholders::_1);
auto bind2 = bind(&f1, placeholders::_1, placeholders::_2);
auto bindpartial = bind(&f1, placeholders::_1, 1);
printf("action : signature : result\n");
printf("----------------------------------------\n");
printf("lambda arity 0: [](){} : %i\n", functor_traits< decltype(lambda0) >::arity );
printf("lambda arity 1: [](int){} : %i\n", functor_traits< decltype(lambda1) >::arity );
printf("lambda arity 2: [](int,int){} : %i\n", functor_traits< decltype(lambda2) >::arity );
printf("func arity 0: void() : %i\n", functor_traits< function<void()> >::arity );
printf("func arity 1: int(int) : %i\n", functor_traits< function<void(int)> >::arity );
printf("func arity 2: char(int,int) : %i\n", functor_traits< function<void(int,int)> >::arity );
printf("C::operator()() arity 0 : %i\n", functor_traits< decltype(oper0) >::arity );
printf("C::operator()(int) arity 1 : %i\n", functor_traits< decltype(oper1) >::arity );
printf("C::operator()(int,int) arity 2 : %i\n", functor_traits< decltype(oper2) >::arity );
///////////////////////////////////////////////////////////////////////////
// Testing the bind arity below:
///////////////////////////////////////////////////////////////////////////
printf("bind arity 0: void() : %i\n", functor_traits< decltype(bind0) >::arity );
printf("bind arity 1: int(int) : %i\n", functor_traits< decltype(bind1) >::arity );
printf("bind arity 2: void(int,int) : %i\n", functor_traits< decltype(bind2) >::arity );
printf("bind arity X: void(int, 1 ) : %i\n", functor_traits< decltype(bindpartial) >::arity );
return 0;
}
While this implementation works in gcc with libstdc++, I'm not quite sure if this is a portable solution since it tries to break apart the results of std::bind() ... The nearly private "_Bind" class that we really shouldn't need to do as users of libstdc++.
So my questions are:
How can we determine the arity of bind results without decomposing the result of std::bind()?
and
How can we implement a full implementation of function_traits that supports bounded arguments as much as possible?
OP, your premises are flawed. You're looking for some kind of routine that can tell you, for any given object x, how many arguments x expects — that is, which of x(), x(a), or x(a,b) is well-formed.
The problem is that any number of those alternatives might be well-formed!
In a discussion on isocpp.org of this very topic, Nevin Liber very correctly writes:
For many function objects and functions, the concepts of arity, parameter type and return type don't have a single answer, as those things are based on how it [the object] is being used, not on how it has been defined.
Here's a concrete example.
struct X1 {
void operator() () { puts("zero"); }
void operator() (int) { puts("one"); }
void operator() (int,int) { puts("two"); }
void operator() (...) { puts("any number"); }
template<class... T>
void operator() (T...) { puts("any number, the sequel"); }
};
static_assert(functor_traits<X1>::arity == ?????);
So the only interface we can actually implement is one where we supply an actual argument count, and ask whether x can be called with that number of arguments.
template<typename F>
struct functor_traits {
template<int A> static const int has_arity = ?????;
};
...But what if it can be called with one argument of type Foo or two arguments of type Bar? It seems that just knowing a (possible) arity of x isn't useful — it doesn't really tell you how to call it. To know how to call x, we need to know more or less what types we're trying to pass to it!
So, at this point, the STL comes to our rescue in at least one way: std::result_of. (But see here for a safer decltype-based alternative to result_of; I use it here only for convenience.)
// std::void_t is coming soon to a C++ standard library near you!
template<typename...> using void_t = void;
template<typename F, typename Enable = void>
struct can_be_called_with_one_int
{ using type = std::false_type; };
template<typename F> // SFINAE
struct can_be_called_with_one_int<F, void_t<typename std::result_of<F(int)>::type>>
{ using type = std::true_type; };
template<typename F> // just create a handy shorthand
using can_be_called_with_one_int_t = typename can_be_called_with_one_int<F>::type;
Now we can ask questions like can_be_called_with_one_int_t<int(*)(float)> or can_be_called_with_one_int_t<int(*)(std::string&)> and get reasonable answers.
You could construct similar traits classes for can_be_called_with_no_arguments, ...with_Type2, ...with_Type1_and_Type2, and then use the results of all three of those traits to build up a complete picture of your x's behavior — at least, the part of x's behavior that is relevant to your particular library.

Why can't I push a const pointer to std::vector?

Consider the piece of code:
class T;
void constructVector(const T* item)
{
std::vector<T*> v;
v.push_back(item);
}
I get an error with MSVC 2010 compiler:
error: C2664: 'void std::vector<_Ty>::push_back(_Ty &&)' : cannot
convert parameter 1 from 'const T *' to 'T *&&' with [
_Ty=T * ] Conversion loses qualifiers
I can see this particular conversion is illegal, but I don't believe my code is semantically wrong. I also believe there's push_back(const T&) variant, why isn't that matched to my call?
Because that's a vector of non-const pointers. It won't convert a const pointer to a non-const pointer. That would defeat the purpose of const.
I believe that the push_back(const T&) is not what you're looking for, because that makes the T object itself const, it does not change the type of T from (*) to (const *).
You could make the vector a vector of const pointers :
void constructVector(const T* item)
{
std::vector<const T*> v;
v.push_back(item);
}
Or you could change your function to take a non-const pointer :
void constructVector(T* item)
{
std::vector<T*> v;
v.push_back(item);
}
Drop const
void constructVector( const T* item);
or
Use:
void constructVector(const T* item)
{
std::vector<const T*> v;
v.push_back(item);
}

Resources