What are the requirements for type T in this case? - c++11

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.

Related

Why template functions cannot deduce brace initializers, but auto-declared variables can? [duplicate]

I understand that, given a braced initializer, auto will deduce a type of std::initializer_list, while template type deduction will fail:
auto var = { 1, 2, 3 }; // type deduced as std::initializer_list<int>
template<class T> void f(T parameter);
f({ 1, 2, 3 }); // doesn't compile; type deduction fails
I even know where this is specified in the C++11 standard: 14.8.2.5/5 bullet 5:
[It's a non-deduced context if the program has] A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter
does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list
type. [ Example:
template void g(T);
g({1,2,3}); // error: no argument deduced for T
—end example ]
What I don't know or understand is why this difference in type deduction behavior exists. The specification in the C++14 CD is the same as in C++11, so presumably the standardization committee doesn't view the C++11 behavior as a defect.
Does anybody know why auto deduces a type for a braced initializer, but templates are not permitted to? While speculative explanations of the form "this could be the reason" are interesting, I'm especially interested in explanations from people who know why the standard was written the way it was.
There are two important reasons for templates not to do any deduction (the two that I remember in a discussion with the guy in charge)
Concerns about future language extensions (there are multiple meanings you could invent - what about if we wanted to introduce perfect forwarding for braced init list function arguments?)
The braces can sometimes validly initialize a function parameter that is dependent
template<typename T>
void assign(T &d, const T& s);
int main() {
vector<int> v;
assign(v, { 1, 2, 3 });
}
If T would be deduced at the right side to initializer_list<int> but at the left side to vector<int>, this would fail to work because of a contradictional argument deduction.
The deduction for auto to initializer_list<T> is controversial. There exist a proposal for C++-after-14 to remove it (and to ban initialization with { } or {a, b}, and to make {a} deduce to the type of a).
The reason is described in N2640:
A {}-list cannot deduce against a plain type parameter T. For example:
template<class T> void count(T); // (1).
struct Dimensions { Dimensions(int, int); };
size_t count(Dimensions); // (2).
size_t n = count({1, 2}); // Calls (2); deduction doesn't
// succeed for (1).
Another example:
template<class T>
void inc(T, int); // (1)
template<class T>
void inc(std::initializer_list<T>, long); // (2)
inc({1, 2, 3}, 3); // Calls (2). (If deduction had succeeded
// for (1), (1) would have been called — a
// surprise.)
On the other hand, being able to deduce an initializer_list<X> for T is attractive to
allow:
auto x = { 1, 1, 2, 3, 5 };
f(x);
g(x);
which was deemed desirable behavior since the very beginning of the EWG discussions about
initializer lists.
Rather than coming up with a clever deduction rule for a parameter type T matched with a {}-list (an option we pursued in earlier sketches and drafts of this paper), we now prefer to handle this with a special case for "auto" variable deduction when the initializer is a {}-list. I.e., for the specific case of a variable declared with an "auto" type specifier and a {}-list initializer, the "auto" is deduced as for a function f(initializer_list<T>) instead of as for a function f(T).
For conclusion, the problem is that if we allow a {}-list to deduce against a plain type parameter T, then the function with parameter T would have very high priority during overload resolution, which may cause wired behavior (like the examples above).
First of all it's "speculative explanations of the form "this could be the reason"" as you call it.
{1,2,3} is not only std::initializer_list<int> but also allow initialize types without constructor. For example:
#include <initializer_list>
struct x{
int a,b,c;
};
void f(x){
}
int main() {
f({1,2,3});
}
is correct code. To show that it isn't initializer_list let's see the following code:
#include <initializer_list>
struct x{int a,b,c;};
void f(x){
}
int main() {
auto il = {1, 2, 3};
f(il);
}
Error is:
prog.cpp: In function ‘int main()’:
prog.cpp:10:9: error: could not convert ‘il’ from ‘std::initializer_list<int>’ to ‘x’
And now to the question "What is the difference?"
in auto x = {1, 2, 3}; code it's OK to determine type, because coder explicitly said "It's not important what's type it is" using auto
While in case of function template he may be sure that he is using different type. And it's good to prevent errors in ambiguous cases (It doesn't seem like C++ style , through).
Especially bad it will be in case when there was 1 function f(x) and then it was changed to template one. Programmer wrote to use it as x, and after adding new function for other type it slightly change to call completely different one.

std::map of non-movable objects [duplicate]

The following code will not compile on gcc 4.8.2.
The problem is that this code will attempt to copy construct an std::pair<int, A> which can't happen due to struct A missing copy and move constructors.
Is gcc failing here or am I missing something?
#include <map>
struct A
{
int bla;
A(int blub):bla(blub){}
A(A&&) = delete;
A(const A&) = delete;
A& operator=(A&&) = delete;
A& operator=(const A&) = delete;
};
int main()
{
std::map<int, A> map;
map.emplace(1, 2); // doesn't work
map.emplace(std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple(2)
); // works like a charm
return 0;
}
As far as I can tell, the issue isn't caused by map::emplace, but by pair's constructors:
#include <map>
struct A
{
A(int) {}
A(A&&) = delete;
A(A const&) = delete;
};
int main()
{
std::pair<int, A> x(1, 4); // error
}
This code example doesn't compile, neither with coliru's g++4.8.1 nor with clang++3.5, which are both using libstdc++, as far as I can tell.
The issue is rooted in the fact that although we can construct
A t(4);
that is, std::is_constructible<A, int>::value == true, we cannot implicitly convert an int to an A [conv]/3
An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed,
for some invented temporary variable t.
Note the copy-initialization (the =). This creates a temporary A and initializes t from this temporary, [dcl.init]/17. This initialization from a temporary tries to call the deleted move ctor of A, which makes the conversion ill-formed.
As we cannot convert from an int to an A, the constructor of pair that one would expect to be called is rejected by SFINAE. This behaviour is surprising, N4387 - Improving pair and tuple analyses and tries to improve the situation, by making the constructor explicit instead of rejecting it. N4387 has been voted into C++1z at the Lenexa meeting.
The following describes the C++11 rules.
The constructor I had expected to be called is described in [pairs.pair]/7-9
template<class U, class V> constexpr pair(U&& x, V&& y);
7 Requires: is_constructible<first_type, U&&>::value is true and
is_constructible<second_type, V&&>::value is true.
8 Effects: The
constructor initializes first with std::forward<U>(x) and second with
std::forward<V>(y).
9 Remarks: If U is not implicitly convertible to
first_type or V is not implicitly convertible to second_type this
constructor shall not participate in overload resolution.
Note the difference between is_constructible in the Requires section, and "is not implicitly convertible" in the Remarks section. The requirements are fulfilled to call this constructor, but it may not participate in overload resolution (= has to be rejected via SFINAE).
Therefore, overload resolution needs to select a "worse match", namely one whose second parameter is a A const&. A temporary is created from the int argument and bound to this reference, and the reference is used to initialize the pair data member (.second). The initialization tries to call the deleted copy ctor of A, and the construction of the pair is ill-formed.
libstdc++ has (as an extension) some nonstandard ctors. In the latest doxygen (and in 4.8.2), the constructor of pair that I had expected to be called (being surprised by the rules required by the Standard) is:
template<class _U1, class _U2,
class = typename enable_if<__and_<is_convertible<_U1, _T1>,
is_convertible<_U2, _T2>
>::value
>::type>
constexpr pair(_U1&& __x, _U2&& __y)
: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
and the one that is actually called is the non-standard:
// DR 811.
template<class _U1,
class = typename enable_if<is_convertible<_U1, _T1>::value>::type>
constexpr pair(_U1&& __x, const _T2& __y)
: first(std::forward<_U1>(__x)), second(__y) { }
The program is ill-formed according to the Standard, it is not merely rejected by this non-standard ctor.
As a final remark, here's the specification of is_constructible and is_convertible.
is_constructible [meta.rel]/4
Given the following function prototype:
template <class T>
typename add_rvalue_reference<T>::type create();
the predicate condition for a template specialization is_constructible<T, Args...> shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:
T t(create<Args>()...);
[Note: These tokens are never interpreted as a function declaration. — end note] Access checking is performed as if in a context unrelated to T and any of the Args. Only the validity of the immediate context of the variable initialization is considered.
is_convertible [meta.unary.prop]/6:
Given the following function prototype:
template <class T>
typename add_rvalue_reference<T>::type create();
the predicate condition for a template specialization is_convertible<From, To> shall be satisfied if and
only if the return expression in the following code would be well-formed, including any implicit conversions
to the return type of the function:
To test() {
return create<From>();
}
[Note: This requirement gives well defined results for reference types, void types, array types, and function types. — end note] Access checking is performed as if in a context unrelated to To and From. Only
the validity of the immediate context of the expression of the return-statement (including conversions to
the return type) is considered.
For your type A,
A t(create<int>());
is well-formed; however
A test() {
return create<int>();
}
creates a temporary of type A and tries to move that into the return-value (copy-initialization). That selects the deleted ctor A(A&&) and is therefore ill-formed.

A function with a std::function parameter does not accept a lamba function

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.

How do I check whether a std::function is bound to a specific object's member function?

I'm looking for a way of checking whether a std::function pointer is bound to a member function of a particular object. I'm aware that std::function itself has no '==' operator. I have however come across the std::function::target method which should be able, in principle, to give me the address of the function to which the pointer is pointing. My starting point was therefore this:
bool MyClass::isThePointerSetToMyMethod(std::function<void (const char*, string)> const& candidate)
{
// Create a pointer to the local reportFileError function using the same syntax that we did in the constructor:
std::function<void (const char *, string)> localFn = std::bind(&MyClass::theLocalMember, this,
std::placeholders::_1, std::placeholders::_2);
// Find the target
auto ptr1 = localFn.target< std::function<void (const char *, string)> >();
// Find the target of the candidate
auto ptr2 = candidate.target< std::function<void (const char *, string)> >();
// Compare the two pointers to see whether they actually point to the same function:
if (!ptr1 || !ptr2) return false;
if (*ptr1 == *ptr2)
return true;
else
return false;
}
This doesn't work, and the reason is that the values of 'ptr1' and 'ptr2' are always returned as null. According to the documentation for the std::function::target method, this must be because the type that I've specified for the target is not correct.
If I look at what target_type(localFn) actually is (using Visual C++ 2013), it's a bit frightening:
class std::_Bind<1,void,struct std::_Pmf_wrap<void (__thiscall MyClass::*)(char const *, string),void,class MyClass,char const *,string>,class MyClass * const,class std::_Ph<1> &,class std::_Ph<2> &>
Nevertheless, target_type(candidate) gives the same result, so I thought I'd try a typedef:
bool MyClass::isThePointerSetToMyMethod(std::function<void (const char*, string)> const& candidate)
{
typedef class std::_Bind<1,void,struct std::_Pmf_wrap<void (__thiscall MyClass::*)(char const *, string),void,class MyClass,char const *,string>,class MyClass * const,class std::_Ph<1> &,class std::_Ph<2> &> wally;
// Create a pointer to the local reportFileError function using the same syntax that we did in the constructor:
std::function<void (const char *, string)> localFn = std::bind(&MyClass::theLocalMember, this,
std::placeholders::_1, std::placeholders::_2);
// Find the target
auto ptr1 = localFn.target< wally >();
// Find the target of the candidate
auto ptr2 = candidate.target< wally >();
// Compare the two pointers to see whether they actually point to the same function:
if (!ptr1 || !ptr2) return false;
if (*ptr1 == *ptr2)
return true;
else
return false;
}
Alas this gets me no further; the values of ptr1 and ptr2 are still null.
So for now I've run out of ideas. Is there anyone reading this who knows either:
(1) The appropriate form for a typedef for a std::function pointer to the member function of a class, or
(2) A better way to achieve my ultimate objective, which is to tell whether a std::function pointer is pointing to a particular object's member function or whether it isn't?
[Background, in case anyone is interested: the reason I'm doing this is that I have a callback table where different callbacks are set to different functions depending on the state that the system is in; this makes state control very simple, as it means that in a given context I can call a given callback and know that the actions taken by the function I've called will be appropriate for the current state, without having to know anything about what that state actually is. Usually, when an object is instantiated which will change the system state, it takes control of the relevant callback(s) and binds them to whatever local member functions are appropriate for whatever state it's in. Under these circumstances, however, the object's destructor ought to return the callbacks to their status quo ante so that they are not left pointing to nothing.
Very rarely, an object may bind the callbacks to its member functions in its constructor, but before its destructor is called another object may take control of the same callbacks itself, and re-bind them to member functions of its own. If this happens, then the first object's destructor needs to be able to recognise that this has happened, and exit without affecting the callbacks' assignment to the second object's methods. The obvious way to do this is for the destructor to be able to check whether the callbacks are still assigned to its own methods or not, and if they are not then to leave well alone.]
Flesh out the callback table into a class which manages the table. All modifications to the table should be done through this class's interface. Internally, you would maintain a stack-like structure which lets you undo the changes done to the callback table. Barebones interface would look something like:
class CallbackTable
{
public:
bool ApplyChanges(...)
{
//Push the old values of the entries that would be changed here into your change-tracker stack and modify the table
}
bool UnApplyChanges(...)
{
//Pop the change-tracker stack and restore the table to the state it was in before the most recent change was applied.
}
};

Is it possible to write a generic function that distiguishes between an rvalue and an lvalue?

I am trying to learn rvalue references, as an exercise I tried to do answer the following.
Is it possible to write a function that can tell (at least at runtime, better if at compile time) if the passed value is a value (non reference), a rvalue or an lvalue? for a generic type? I want to extract as much information about the type as possible.
An alternative statement of the problem could be:
Can I have a typeid-like function that can tell as much as possible about the calling expression?, for example (and ideally) if the type is T, T&, T const&, or T&&.
Currently, for example, typeid drops some information about the type and one can do better (as in the example the const and non-const reference are distiguished). But how much better than typeid can one possibly do?
This is my best attempt so far. It can't distinguish between a rvalue and a "constant". First and second case in the example).
Maybe distiguishing case 1 and 2 is not possible in any circumstance? since both are ultimately rvalue? the the question is Even if both are rvalues can the two cases trigger different behavior?
In any case, it seems I overcomplicated the solution as I needed to resort to rvalue conditional casts, and ended up with this nasty code and not even 100% there.
#include<iostream>
#include<typeinfo>
template<class T>
void qualified_generic(T&& t){
std::clog << __PRETTY_FUNCTION__ << std::endl;
std::clog
<< typeid(t).name() // ok, it drops any qualification
<< (std::is_const<typename std::remove_reference<decltype(std::forward<T>(t))>::type>::value?" const":"") // seems to detect constness rigth
<< (std::is_lvalue_reference<decltype(std::forward<T>(t))>::value?"&":"")
<< (std::is_rvalue_reference<decltype(std::forward<T>(t))>::value?"&&":"") // cannot distiguish between passing a constant and an rvalue expression
<< std::endl
;
}
using namespace std;
int main(){
int a = 5;
int const b = 5;
qualified_generic(5); // prints "int&&", would plain "int" be more appropriate?
qualified_generic(a+1); // prints "int&&" ok
qualified_generic(a); // print "int&", ok
qualified_generic(b); // print "int const&", ok
}
Maybe the ultimate solution to distiguish between the cases will involve detecting a constexpr.
UPDATE: I found this talk by Scott Meyers where he claims that "The Standard sometimes requires typeid to give the 'wrong' answer". http://vimeo.com/97344493 about minute 44. I wonder if this is one of the cases.
UPDATE 2015: I revisited the problem using Boost TypeIndex and the result is still the same. For example using:
template<class T>
std::string qualified_generic(T&& t){
return boost::typeindex::type_id_with_cvr<decltype(t)>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T&&>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T&>().pretty_name();
}
Still it is not possible to distinguish the type of 5 and a+1 in the above example.

Resources