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

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.

Related

C++ Check if generic object has member function matching signature

first post, so hopefully not violating any etiquette. Feel free to give suggestions for making the question better.
I've seen a few posts similar to this one: Check if a class has a member function of a given signature, but none do quite what I want. Sure it "works with polymorphism" in the sense that it can properly check subclass types for the function that comes from a superclass, but what I'd like to do is check the object itself and not the class. Using some (slightly tweaked) code from that post:
// Somewhere in back-end
#include <type_traits>
template<typename, typename T>
struct HasFunction {
static_assert(integral_constant<T, false>::value,
"Second template parameter needs to be of function type."
);
};
template<typename C, typename Ret, typename... Args>
class HasFunction<C, Ret(Args...)> {
template<typename T>
static constexpr auto check(T*) -> typename is_same<
decltype(declval<T>().myfunc(declval<Args>()...)), Ret>::type;
template<typename>
static constexpr false_type check(...);
typedef decltype(check<C>(0)) type;
public:
static constexpr bool value = type::value;
};
struct W {};
struct X : W { int myfunc(double) { return 42; } };
struct Y : X {};
I'd like to have something like the following:
// somewhere else in back-end. Called by client code and doesn't know
// what it's been passed!
template <class T>
void DoSomething(T& obj) {
if (HasFunction<T, int(double)>::value)
cout << "Found it!" << endl;
// Do something with obj.myfunc
else cout << "Nothin to see here" << endl;
}
int main()
{
Y y;
W* w = &y; // same object
DoSomething(y); // Found it!
DoSomething(*w); // Nothin to see here?
}
The problem is that the same object being viewed polymorphically causes different results (because the deduced type is what is being checked and not the object). So for example, if I was iterating over a collection of W*'s and calling DoSomething I would want it to no-op on W's but it should do something for X's and Y's. Is this achievable? I'm still digging into templates so I'm still not quite sure what's possible but it seems like it isn't. Is there a different way of doing it altogether?
Also, slightly less related to that specific problem: Is there a way to make HasFunction more like an interface so I could arbitrarily check for different functions? i.e. not have ".myfunc" concrete within it? (seems like it's only possible with macros?) e.g.
template<typename T>
struct HasFoo<T> : HasFunction<T, int foo(void)> {};
int main() {
Bar b;
if(HasFoo<b>::value) b.foo();
}
Obviously that's invalid syntax but hopefully it gets the point across.
It's just not possible to perform deep inspection on a base class pointer in order to check for possible member functions on the pointed-to type (for derived types that are not known ahead of time). Even if we get reflection.
The C++ standard provides us no way to perform this kind of inspection, because the kind of run time type information that is guaranteed to be available is very limited, basically relegated to the type_info structure.
Your compiler/platform may provide additional run-time type information that you can hook into, although the exact types and machinery used to provide RTTI are generally undocumented and difficult to examine (This article by Quarkslab attempts to inspect MSVC's RTTI hierarchy)

C++ why overloading (T&) in template with (T*)

in C++, if a method is accepting left reference + pointer only,
it seems it suffices if we only have a template method with T& as its parameter, why we usually overload with test(T* ) as well ?
proof of concept: left reference method can take pointer argument.
#include <iostream>
using namespace std;
template<class T>
void test(T& arg) {
T value = arg;
cout << *value << endl;
}
int main() {
int b = 4;
int* a = &b;
test(a); // compiles and runs without issue.
return 0;
}
Why [do] we usually overload with test(T* ) as well?
I am not sure that we usually do anything of the sort, but if one were to overload for a pointer, it would be because pointers behave differently than object types. Remember, a pointer in fact is not an object but an address to an object.
The reason that test(a) compiles and runs without issue is because it is accepting a reference to a pointer to an object as its parameter. Thus, when the line cout << *value << endl; executes, the pointer is dereferenced back to an object and we see 4 printed to standard out.
As #HolyBlackCat mentioned, we usually want do different things for T& and T*.
As indicated in the example, for test(T&) we usually need to manually do dereference, this would result in the difference in the behavior, so it makes sense to have a overload like this.

Access variables in struct from void pointer

I was wondering if there is a way to access a data member within a struct that is being pointed to by a void*? What I'm trying to explain will hopefully be more apparent in my example code:
int main()
{
struct S
{
int val;
};
S s;
s.val = 5;
void* p;
p = malloc(sizeof(S));
*(struct S*) p = s;
std::cout<< *(struct S*)p.val << std::endl;
}
I have ran this exact code casting p as *(int*)p and it printed fine, however, using exact code above results in a compilation error. Haven't been able to find an example that quite accomplishes this task. Is it possible to access the data members of the struct after it is casted? why or why not? if so, how?
The . operator has higher precedence than a C-style cast. So *(struct S*)p.val is treated as *((struct S*)(p.val)), which doesn't make sense since p is a pointer and does not have members.
So you need parentheses to specify what you intended:
std::cout<< (*(struct S*)p).val << std::endl;
Or equivalently,
std::cout<< static_cast<S*>(p)->val << std::endl;
[But also: the statement *(struct S*) p = s; technically has undefined behavior, even though all most implementations will allow it. This is because C++ has rules about when an object is created, and there was no object of type S previously at that address, and assignment does not create an object except for some cases involving union members. A similar statement that does not have this problem would be new(p) S{s};.
Also also: use of malloc or void* is usually not a good idea in C++ in the first place. malloc should only be used when interfacing with a C library that requires it. Anything for which void* seems useful can probably be done more safely using templates. In a few cases a void* might be the only way to do something or "cleverly" avoid code duplication or something, but still use it sparingly and always with extreme caution.]

why does std::for_each iterator need a copy constructable iterator

I noticed that std::for_each requires it's iterators to meet the requirement InputIterator, which in turn requires Iterator and then Copy{Contructable,Assignable}.
That's not the only thing, std::for_each actually uses the copy constructor (cc) (not assignment as far as my configuration goes). That is, deleting the cc from the iterator will result in:
error: use of deleted function ‘some_iterator::some_iterator(const some_iterator&)’
Why does std::for_each need a cc? I found this particularly inconvenient, since I created an iterator which recursively iterates through files in a folder, keeping track of the files and folders on a queue. This means that the iterator has a queue data member, which would also have to be copied if the cc is used: that is unnecessarily inefficient.
The strange thing is that the cc is not called in this simple example:
#include <iostream>
#include <iterator>
#include <algorithm>
class infinite_5_iterator
:
public std::iterator<std::input_iterator_tag, int>
{
public:
infinite_5_iterator() = default;
infinite_5_iterator(infinite_5_iterator const &) {std::cout << "copy constr "; }
infinite_5_iterator &operator=(infinite_5_iterator const &) = delete;
int operator*() { return 5; }
infinite_5_iterator &operator++() { return *this; }
bool operator==(infinite_5_iterator const &) const { return false; }
bool operator!=(infinite_5_iterator const &) const { return true; }
};
int main() {
std::for_each(infinite_5_iterator(), infinite_5_iterator(),
[](int v) {
std::cout << v << ' ';
}
);
}
source: http://ideone.com/YVHph8
It however is needed compile time. Why does std::for_each need to copy construct the iterator, and when is this done? Isn't this extremely inefficient?
NOTE: I'm talking about the cc of the iterator, not of it's elements, as is done here: unexpected copies with foreach over a map
EDIT: Note that the standard does not state the copy-constructor is called at all, it just expresses the amount of times f is called. May I then assume that the cc is not called at all? Why is the use of operator++ and operator* and cc not specified, but the use of f is?
You have simply fallen victim to a specification that has evolved in bits and pieces over decades. The concept of InputIterator was invented a long time before the notion of move-only types, or movable types was conceived.
In hindsight I would love to declare that InputIterator need not be copyable. This would mesh perfectly with its single-pass behavior. But I also fear that such a change would have overwhelming backwards compatibility problems.
In addition to the flawed iterator concepts as specified in the standard, about a decade ago, in an attempt to be helpful, the gcc std::lib (libstdc++) started imposing "concepts" on things like InputIterator in the std-algorithms. I.e. because the standard says:
Requires: InputIterator shall satisfy the requirements of an input iterator (24.2.3).
then "concept checks" were inserted into the std-algorithms that require InputIterator to meet all of the requirements of input iterator whether or not the algorithm actually used all of those requirements. And in this case, it is the concept check, not the actual algorithm, that is requiring your iterator to be CopyConstructible.
<sigh>
If you write your own for_each algorithm, it is trivial to do so without requiring your iterators to be CopyConstructible or CopyAssignable (if supplied with rvalue iterator arguments):
template <class InputIterator, class Function>
inline
Function
for_each(InputIterator first, InputIterator last, Function f)
{
for (; first != last; ++first)
f(*first);
return f;
}
And for your use case I recommend either doing that, or simply writing your own loop.

Uniqueness of std::unique_ptr

I have been working on std::unique_ptr s but confused at some point about its semantics. From the documentation,
No two unique_ptr instances can manage the same object
But, even tough it is most probably a silly example, consider such a code.
std::unique_ptr<int> a(new int(10));
std::unique_ptr<int> b = std::unique_ptr<int>(a.get());
std::cout << *b << std::endl;
*a = 5;
std::cout << *b;
a and b is managing the same object here, and the output is 10 5. And of course I am getting an assertion failure error at the end on debug mode due to two unique ptrs trying to destruct same object at the end of scope.
I know it is silly and such usage is not advised, but I came across to this when it was not very obvious ( a class member calling another etc. ) and the assertion failure was the thing I started with.
My question is what the above sentence exactly means: it is posed by the standard and a decent compiler shouldnt allow you to do it (i am on vs2013 btw) or you must do it that way ( never cause two unique_ptrs point to same object) ( unlikely since the purpose of unique_ptrs is to make us less worried i suppose.) Or I should never use anything about raw pointers ( a.get() ) when unique_ptr s are involved.
Your last sentence is correct. As soon as you use raw pointers with a.get() as in the line below, you have thrown away all the promises that std::unique_ptr make to you.
std::unique_ptr<int> b = std::unique_ptr<int>(a.get());
The correct semantic to preserve the uniqueness while converting to a raw pointer would be to use a.release().
std::unique_ptr<int> b = std::unique_ptr<int>(a.release());
Of course, you would normally just use assignment or initializatoin with std::move if you were moving ownership between two std::unique_pointer instances, as given by the documentation. Either of the two lines below should be valid.
std::unique_ptr<int> b(std::move(a));
std::unique_ptr<int> b = std::move(a);
To make the std::move semantics more clear, consider the following test program.
#include <stdio.h>
#include <memory>
#include <stdlib.h>
int main(){
std::unique_ptr<int> a(new int(10));
printf("%p\n", a.get());
std::unique_ptr<int> b(std::move(a));
printf("%p\n", a.get());
printf("%p\n", b.get());
}
On my system, the output is the following. Observe that the first line and the last line match.
0x1827010
(nil)
0x1827010

Resources