Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an std function that only returns its parameter?

Tags:

c++

stl

That should be trivial to implement, something like

template<typename T>
T & as_is(T & t) { return t; }

Still, I'd like not to have to write it (:

I did not find such a thing on www.cplusplus.com.

For those who will ask "what are you trying to do", here is the thing. I have a class that builds ascii tables, with nice padding and everything. I'll spare the details. The important thing is that it stores strings (so it's able to calculate how much to pad). I want to implement a sort function and be able to tell the class to use the column as a certain type. If I want to sort by a column of ints (which, again, are internally strings), i'd pass atoi. If sorting strings, I want to pass as_is, or the stl equivalent, if any.

like image 933
Gabriel Avatar asked Sep 26 '12 21:09

Gabriel


2 Answers

Why not overload the function and not pass anything?

Btw, if you're working with MSVC, they have the identity class template, which has an overloaded operator() that returns the input. So in theory, you could pass std::identity<std::string>(), but I'd say, just build your own identity function.

like image 120
Xeo Avatar answered Sep 29 '22 07:09

Xeo


You cannot pass a template as though it were a function, so neither std::forward nor your hypothetical nonstd::identity function will work as-is (as it were). You'd need to explicitly set the target type of the transform:

table.SortColumnUsing(3, nonstd::identity<std::string>);

That seems a bit ugly to me, because the type in the template specialization is a feature of the internal implementation of table, rather than having anything to do with the type I'm expecting the table to serialize into for the purposes of sorting. Or perhaps you don't really store the columns as std::string.

How does atoi work as a type descriptor? atoi expects a char*, not a std::string, and I didn't think you could implicitly convert int(const char*) into int(const std::string&). Even if you could do that, what type do you use which can store both an int(const std::string&) and a Banana(const std string&). Perhaps I don't fully understand the context of your question, or alternatively you have some C++ tricks up your sleeve which I'd love to learn.

My inclination would be to pass a comparison function rather than a conversion function. That would result in a single constant function type, maybe bool(const std::string&, const std::string&). That might also make it simpler to implement eg. case-insensitive or locale-specific string comparison for particular columns, or other UI-convenient sorting hacks (like putting folders at the top of the list: first check if only one of the strings has a trailing /, otherwise use standard comparison.) That doesn't really solve the specialization issue, though; for the std::string case, you still end up with std::less<std::string> (which at least exists.)

Not a great answer, I know... but it was too long for a comment.

like image 43
rici Avatar answered Sep 29 '22 06:09

rici