I have a probleme by using max_element with 3 parametres :
My list
list<T*> myList_;
the function
template<typename T>
T TheObject<T>::bigger () const{
return *(*(max_element(myList_.begin(), myList_.end(), compare)));
}
template<typename T>
bool TheObject<T>::compare(const T* a, const T* b)
{
return *a < *b;
}
Why I have this error
Error 1 : 'TheObject::compare': function call missing argument
list; use '&TheObject::compare' to create a pointer to member obj.h
Error 2 : '_FwdIt std::max_element(_FwdIt,_FwdIt)' : expects 2
arguments - 3 provided obj.h
The function you provide to std::max_element (and other standard algorithms) cannot be a non-static member function, since it will not be called as a member function. (std::max_element has no idea what this might be.)
The first error message you're getting is accurate, but possibly misleading. Because compare is not a free-standing function, but rather a non-static member function, you cannot use it as a function pointer, only as a pointer-to-member-function. And the syntax of a pointer-to-member-function is &Class::member. Fixing that won't help, though, because std::max_element cannot make use of a pointer-to-member-function as its third argument.
Related
Given the following function:
template<class T, typename Iterator, typename Function >
T map_reduce(Iterator start, Iterator end, Function f) {
std::Vector<T> vec;
for(; start != end; ++start){
vec.push_back(f(*start));
}
return *start;
}
Can someone explain me why the type T must in this case operator= and Constructor missing parameters and copy c'tor ?
I think that T must copy c'tor because the function return it by-value. But I don't have idea why T must also constructor missing parameters and operator=.
From cppreference:
void push_back( const T& value ); (1)
void push_back( T&& value ); (2)
Type requirements
T must meet the requirements of CopyInsertable in order to use overload (1).
T must meet the requirements of MoveInsertable in order to use overload (2).
Which of these is selected depends on the type of f. Let's assume that f returns an lvalue-reference, which matches (1), because that's the more restrictive one.
That requires, given
std::allocator<T> m;
T* p;
the expression
std::allocator_traits<std::allocator<T>>::construct(m, p, f(*start));
to be well-formed. The note helpfully informs us, in this case, that will be
::new((void*)p) T(f(*start))
You are also (copy?) constructing a T in the return value, when you return *start;. This is likely the source of your "constructor missing parameters" error, as I would expect *start to only relate to T via f.
Note that this is rather likely to be undefined behaviour, as you have just incremented start until it is equal to end. Someone trying to map_reduce everything in a container will pass a non-dereferenceable iterator as end.
As for the missing operator=, who knows? You haven't provided any context to the types involved in the instantiation of this error.
i do not understand "R (F::* /mf/)" ,R is a type ,after R it should be a reference parameters
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv) const)
{
return TypeAdaptor<R>(fn);
}
It's a pointer to a member function. In particular:
R (F::* mf)(const SemanticValues& sv) const
is
* mf: a pointer named mf (whose name is commented out)...
F::: ...to a member function of F...
const SemanticValues& sv: ...which accepts a const reference to SemanticValues...
R: ...and returns a value of type R...
const: ...and is itself const.
It is a type for some pointer to member function.
BTW, in many cases, you could prefer using std::function with lambda expressions.
This is part of an assignment, I am stuck at this instruction:
Sort your randomly generated pool of schedules.
Use std::stable_sort,
passing in an object of type schedule_compare as the custom comparison
operator.
UPDATE: I was checking cppreference stable_srot(), see method definition below:
void stable_sort ( RandomAccessIterator first, RandomAccessIterator
last,Compare comp );
, and it seems from what I understood is that you can only pass functions to the last argument (Compare comp) of the stable_sort() i.e:
However, in the instructions, it says that you need to pass an object of type schedule_compare. How is this possible ?
This is my code below:
struct schedule_compare
{
explicit schedule_compare(runtime_matrix const& m)
: matrix_{m} { }
bool operator()(schedule const& obj1, schedule const& obj2) {
if (obj1.score > obj2.score)
return true;
else
return false;
}
private:
runtime_matrix const& matrix_;
};
auto populate_gene_pool(runtime_matrix const& matrix,
size_t const pool_size, random_generator& gen)
{
std::vector<schedule> v_schedule;
v_schedule.reserve(pool_size);
std::uniform_int_distribution<size_t> dis(0, matrix.machines() - 1);
// 4. Sort your randomly generated pool of schedules. Use
// std::stable_sort, passing in an object of type
// schedule_compare as the custom comparison operator.
std::stable_sort(begin(v_schedule), end(v_schedule), ???)
return; v_schedule;
}
For algorithm functions that accepts a "function" (like std::stable_sort) you can pass anything that can be called as a function.
For example a pointer to a global, namespace or static member function. Or you can pass a function-like object instance (i.e. an instance of a class that has a function call operator), also known as a functor object.
This is simply done by creating a temporary object, and passing it to the std::stable_sort (in your case):
std::stable_sort(begin(v_schedule), end(v_schedule), schedule_compare(matrix));
Since the schedule_compare structure have a function call operator (the operator() member function) it can generally be treated like any other function, including being "called".
Consider this:
int func1( int i );
int func2( int i );
Conditional operator can be used like that:
int res = (cond)?func1(4):func2(4);
Or, if both may use the same parameter:
int res = ((cond)?func1:func2)(4);
Now, what about member functions of a class:
class T
{
public:
T( int i ) : i(i) {}
int memfunc1() { return 1*i; }
int memfunc2() { return 2*i; }
private:
int i;
};
I tried this, but it does not work:
T t(4);
int res2 = t.((cond)?memfunc1:memfunc2)();
...tried other syntax too ((t.*((cond)?&(T::memfunc1):&(T::memfunc2)))()) with no success...
Is that doable and then what would be the good syntax? One line code answer are preferable (using a temporary auto variable to store pointer to function would be too easy...;-)
§ 5.3.1 [expr.unary.op]/p4:
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed
in parentheses. [ Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in
parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because
there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to
member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is
&unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. — end note ]
If it still doesn't help, you can uncover the correct syntax below:
(t.*(cond ? &T::memfunc1 : &T::memfunc2))()
I am trying to get more familiar with the C++11 standard by implementing the std::iterator on my own doubly linked list collection and also trying to make my own sort function to sort it.
I would like the sort function to accept a lamba as a way of sorting by making the sort accept a std::function, but it does not compile (I do not know how to implement the move_iterator, hence returning a copy of the collection instead of modifying the passed one).
template <typename _Ty, typename _By>
LinkedList<_Ty> sort(const LinkedList<_Ty>& source, std::function<bool(_By, _By)> pred)
{
LinkedList<_Ty> tmp;
while (tmp.size() != source.size())
{
_Ty suitable;
for (auto& i : source) {
if (pred(suitable, i) == true) {
suitable = i;
}
}
tmp.push_back(suitable);
}
return tmp;
}
Is my definition of the function wrong? If I try to call the function, I recieve a compilation error.
LinkedList<std::string> strings{
"one",
"two",
"long string",
"the longest of them all"
};
auto sortedByLength = sort(strings, [](const std::string& a, const std::string& b){
return a.length() < b.length();
});
Error: no instance of function template "sort" matches the argument
list argument types are: (LinkedList, lambda []bool
(const std::string &a, const std::string &)->bool)
Additional info, the compilation also gives the following error:
Error 1 error C2784: 'LinkedList<_Ty> sort(const
LinkedList<_Ty> &,std::function)' : could not
deduce template argument for 'std::function<bool(_By,_By)>'
Update: I know the sorting algorithm is incorrect and would not do what is wanted, I have no intention in leaving it as is and do not have a problem fixing that, once the declaration is correct.
The problem is that _By used inside std::function like this cannot be deduced from a lambda closure. You'd need to pass in an actual std::function object, and not a lambda. Remember that the type of a lambda expression is an unnamed class type (called the closure type), and not std::function.
What you're doing is a bit like this:
template <class T>
void foo(std::unique_ptr<T> p);
foo(nullptr);
Here, too, there's no way to deduce T from the argument.
How the standard library normally solves this: it does not restrict itself to std::function in any way, and simply makes the type of the predicate its template parameter:
template <typename _Ty, typename _Pred>
LinkedList<_Ty> sort(const LinkedList<_Ty>& source, _Pred pred)
This way, the closure type will be deduced and all is well.
Notice that you don't need std::function at all—that's pretty much only needed if you need to store a functor, or pass it through a runtime interface (not a compiletime one like templates).
Side note: your code is using identifiers which are reserved for the compiler and standard library (identifiers starting with an underscore followed by an uppercase letter). This is not legal in C++, you should avoid such reserved identifiers in your code.