Tuple and variadic templates, how does this work? - c++

I have seen people write (on stack overflow itself, asking some even advanced concepts) something along the lines of:
template<typename... args>
std::tuple<args...> parse(istream stream)
{
return std::make_tuple(args(stream)...);
}
and use it as
auto tup = parse<int, float, char>(stream);
How does the above code construct the tuple by parsing the stream? Is there any specific requirement on how data is to be put into the stream?

For this to work there must be an implicit conversion from std::istream to all the types specified as template arguments.
struct A {
A(std::istream&) {} // A can be constructed from 'std::istream'.
};
struct B {
B(std::istream&) {} // B can be constructed from 'std::istream'.
};
int main() {
std::istringstream stream{"t1 t2"};
auto tup = parse<A, B>(stream);
}
It works by expanding the variadic list of types and constructs each type with the supplied std::istream as argument. It is then left to the constructor of each type to read from the stream.
Also be aware that the evaluation order of the constructors is not specified so you can't expect that the first type in the variadic list will read from the stream first etc.
The code as it is does not work with built in types as int, float and char as there is no conversion from std::istream to any of those types.

It works poorly. It relies on the target type having a constructor that takes an std::istream.
As many types don't have this, and you cannot add it to something like int, this is a bad plan.
Instead do this:
template<class T>
auto read_from_stream( std::istream& stream, T* unused_type_tag )
-> typename std::decay<decltype( T{stream} )>::type
{
return {stream};
}
template<class T>
auto read_from_stream( std::istream& stream, T* unused_type_tag, ... )
-> typename std::decay<decltype( T(stream) )>::type
{
return T(stream);
}
template<typename... args>
std::tuple<args...> parse(std::istream& stream) {
return std::tuple<args...>{
read_from_stream(stream, (args*)nullptr)...
};
}
now instead of directly constructing the arguments, we call read_from_stream.
read_from_stream has two overloads above. The first tries to directly and implicitly construct our object from an istream. The second explicitly constructs our object from an istream, then uses RVO to return it. The ... ensures that the 2nd one is only used if the 1st one fails.
In any case, this opens up a point of customization. In the namespace of a type X we can write a read_from_stream( std::istream&, X* ) function, and it will automatically be called instead of the default implementation above. We can also write read_from_stream( std::istream&, int* ) (etc) which can know how to parse integers from an istream.
This kind of point of customization can also be done using a traits class, but doing it with overloads has a number of advantages: you can inject the customizations adjacent to the type, instead of having to open a completely different namespace. The custom action is also shorter (no class wrapping noise).

Related

spawn a copy as input to function taking rvalue reference

I have a library function (not under my control here) which take an r value reference to the movable and copyable type Bar:
void foo(Bar&& b);
In my own code, I sometimes need to give it a copy of an existing value, such as
const auto b = getBar();
foo(mk_copy(b));
b.baz();
This is what comes to mind,
template<typename T> auto mk_copy(T val){return val;}
Is there a standard way to do this, or a more common pattern? Perhaps even
template<typename T> auto mk_copy(T&& val){return std::forward<T>(val);}
Or, as pscill points out just writing the name of the class again,
foo(Bar(b));
but I prefer not to repeat type names.
For the built-in types the prefix + plays the role of “make a copy”:
void foo( char&& ) {}
void bar( double*&& ) {}
auto main() -> int
{
char x{};
foo( +x );
double* p{};
bar( +p );
}
Still, it would probably be confusing to readers of the code if you applied prefix + to some other type, and a general prefix operator+ template might end up in conflict with some class' own prefix operator+.
So, I suggest using the now apparent naming convention for makers, namely a make prefix.
Then it can look like this:
template< class Type >
auto make_copy( Type const& o ) -> Type { return o; }
Your first proposed solution,
template<typename T> auto mk_copy(T val){return val;}
suffers from potentially copying the value twice: first copying to the by-value argument, and then copying to the function result.
This is not a problem for a movable type such as a standard library container, because the return type copying will reduce to a move. But it can be a problem for largish non-movable type, as can occur in legacy code.
The second proposed solution,
template<typename T> auto mk_copy(T&& val){return std::forward<T>(val);}
takes the argument by forwarding reference (a.k.a. universal reference), and then deduces the return type from a re-creation of the argument type. The return type will always be a non-reference, since that's what plain auto deduces, so this is technically correct. But it's needlessly complicated.
There is no standard mechanism, but if you want one, your examples aren't very good. The first mk_copy copies T twice (or copies and moves). The second one seems very confusing as to what it's trying to do.
The obvious way is to simply take a const T&, like you normally would:
template<typename T> T mk_copy(const T &val){return val;}
I think you'd better just define that mk_copy method, or add one more declaration:
auto b_copy = b;
foo(std::move(b_copy));
These are clearer to the readers.
Just to demonstrate the possibilities, you could use decltype to get the type:
foo(std::decay_t<decltype(b)>{b});
or you could get the same effect with lambdas:
foo([&]{return b;}());
or tuples:
foo(std::get<0>(std::make_tuple(b)));
or pairs:
foo(std::make_pair(b, 0).first);

How to obtain "assignable type" for an arbitrary (STL) output iterator in C++

The C++ Standard requires that the typedef value_type in std::iterator_traits<OutputIterator> is set to void for an output iterator of type OutputIterator. Nevertheless, it is perfectly reasonable (and absolutely required in my code) to deduce - for a given output iterator type OutputIterator -, what will be the admissible type (without referring to any implicit conversion) o in an expression of the form
*it = o
where it is an object of type OutputIterator.
Ideally, I'd like to use TMP to define a template class my_iterator_traits which defines a typedef assignable_type, so that my_iterator_traits<OutputIterator>::assignable_type would equal decltype( o ). Any suggestions how to achieve this?
I even do not know how to achieve this if I enumerate all possible STL iterator types by defining template specializations. For example, the following code won't compile, as the compiler cannot deduce the template parameter T:
template <typename Iterator> struct my_iterator_traits;
//[...]
//Does NOT compile, compiler cannot deduce type T
template <typename T> struct my_iterator_traits<std::vector<T>::iterator>
{
typedef typename std::vector<T>::value_type assignable_type;
//Another option, but I think not so clean:
//typedef T assignable_type;
};
EDIT: This is a sketch (without context) for a case where I run into the problem. Suggest that you want to edit elements of a container on the binary level. The object first is an (input) iterator, which allows me to access input elements of a known size (of 2 bytes in this case). I want to write them to a "binary output" via an output iterator result which accepts single byte (output) objects. I.e., I do not want to specify what the "single byte type" of the output iterator should be. (Quasi-)Code:
const typename my_iterator_traits<OutputIterator>::assignable_type* ptr;
for( size_type i = 0; i < n; ++i, ++first )
{
ptr = reinterpret_cast<const typename my_iterator_traits<OutputIterator>::assignable_type*>( &( *first ) );
*result = ptr[0]; ++result;
*result = ptr[1]; ++result;
}
I fear that without the reinterpret_cast it might happen that there exist cases where some implicit conversion alters the binary structure. I just want to copy the bits to the target, no matter what the target is and how it can be accessed via the abstract interface that is provided by the output iterator. The only requirement is that the target can be accessed byte by byte via the output iterator.
Your question cannot be answered in general.
As an example, here is an output iterator that, while it technically only takes one type to operator=, actually takes any type:
template<class OS>
struct ostream_proxy {
void* v;
void(*f)(void*, OS&);
template<class O>
friend O& operator<<(O& o, ostream_proxy p) {
p.f(p.v, o);
return o;
}
template<class X, class pX = typename std::decay_t<X>::type*>
ostream_proxy( X&& x ):
v(&x),
f(
[](void* px, OS& os) {
os << &static_cast<pX>(px);
}
)
{}
};
template<class OS>
std::ostream_iterator<ostream_proxy<OS>> it_out(OS& os) {
return {os};
}
template<class OS, class CharT>
std::ostream_iterator<ostream_proxy<OS>> it_out(OS& os, const CharT* delim) {
return {os, delim};
}
now above I was lazy, and I used std::ostream_iterator with a proxy type. However, it is legal for operator= on an output iterator to be overloaded, or be a template operator. And if that is the case, then there is no "one type without conversion" that the output iterator accepts.
(A less lazy/hacky version would reimplement ostream_iterator<> to have a template operator=, and just write any type out. In my opinion, this would be a good implementation of std::ostream_iterator<void>, like std::less<void> (aka std::less<>)).
It is easy to check if there is a way to assign a given type to the iterator, but determining what type involves "no conversions" is not possible in the general case. In specific cases, there are a myriad of hacks.
Like most "given a function object, give me its signature" this question assumes that there is a fixed type, or there should be a fixed type, involved. Output iterators have valid expressions that can be used to load them, not specific types.

How do I avoid the extra copy in the generic function template?

Background
I have some generic code for persistence that uses boost::variant to store multiple types. While outputting values, I had to write a converter function protected_backslash_n, which does nothing, in the default case, but return the same value back.
In the specialised case where the template parameter is a std::string I use boost::regex_replace() to search for \n and replace it with \\n.
Question
The code works fine, but it would be nice if I could get rid of the extra copy in the generic case, due to the return-by-value.
Is there a way to do this while allowing the specialised std::string version to work fine?
I tried changing the return value to T const&, but then the specialised version won't match up.
Error
GetPipedValues.hpp:15:21: error: template-id ‘protect_backslash_n<std::string>’ for ‘std::string pitbull::protect_backslash_n(const string&)’ does not match any template declaration
Code
template<typename T>
inline T protect_backslash_n( T const& orig )
{
return orig; // BAD: extra copy - how do I get rid of this?
}
template<>
inline std::string protect_backslash_n<std::string>( std::string const& orig )
{
boost::regex expr("(\\n)");
std::string fmt("(\\\\n)");
return boost::regex_replace(
orig, expr, fmt, boost::match_default | boost::format_all
);
}
Don't make it a template, but just an overload. The compiler will choose that function over a template instantiation, if the parameter matches.
std::string protect_backslash_n( std::string const& orig);
That should be simple:
template <typename T>
T const& protect_backslash_n(T const& orig)
{
return orig;
}
And the std::string version as you had it. Maybe you will need additional overloads, e.g. taking a nonconst reference. In C++11 that function should mimic std::forward<T> in the default case.

How does overloading function call work in C++?

I read that function call () can also be overloaded. http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
What would the following mean?
It works.
template<typename T, typename Comp>
struct bind{
T v;
Comp comp;
bool operator()(const T& b){
return comp(b,v);
}
};
int main(){
bind<int, less<int> > b;
b.v = 2;
cout << b(3) << "\n";
}
It means that if you create an object of type bind<>, you can apply the function-call operator to that object.
Like this:
bind<int, std::less<int>> b;
b.v = 2;
std::cout << b(1) << "\n";
That snippet might print "true" on the standard output.
If you have a class called foo, I'm sure you understand what it means to call a member function of an object of that type:
foo f;
f.bar();
You may also understand that you can overload certain operations. For example, you could overload operator+ for foo so that you could do something like this:
foo f, g;
f + g;
Now you can also overload operator() for a class, which allows you to call it as though it were a function:
foo f;
f();
Yes, f is not a function but it is an object of class type that overloads operator(). Class types that do this are known as functors or function objects.
In the example you've given, bind is a functor. When you create an object of that type, you can call it like a function, passing it a const T& and it will return a bool back to you. The implementation of operator() actually calls the function stored in comp, passing it both the T object you passed to operator(), a, and the member object v of type T.
As it stands, it doesn't mean much of anything except "syntax error". For example:
template<T, Op>
This simply isn't allowed. For each template parameter, you need to specify whether it's a type (using class or typename) or a non-type parameter such as an int. Since the apparent intent is that both these should be type parameters, you need something like:
template <class T, class Op>
or:
template <typename T, typename Op>
For this situation, there's no difference in meaning between class and typename.
struct bind{
T v;
Leaving v uninitialized will lead to undefined behavior, so you probably don't want to allow that. You'd normally prevent it by adding a constructor that takes a T as its parameter and initializes v to that value:
bind(T const &v) : v(v) {}
When you include a constructor like this, the compiler won't automatically generate a default constructor, so it's no longer possible to create a bind object with v uninitialized -- exactly what we wanted.
Although creating the comp object:
Op comp;
is fairly harmless, it's also quite unnecessary. You could just as well do the comparison with a temporary instance created with Op(), in which case this:
bool operator()(const T& a){
return comp(a,v);
}
...would become something like this (and the Op comp; simply removed):
bool operator()(T const &a) {
return Op()(a, v);
}
Even with the corrections, I'd consider this code obsolescent. In C++98/03, it would have been useful in a situation where you needed to supply a functor to an algorithm, such as:
std::remove_copy_if(a.begin(), a.end(), bind<int,
std::back_inserter(b),
bind<int, std::less<int> >(5));
...which would copy numbers from a to b, removing those less that 5.
In C++11, however, most (if not all) uses of this bind should probably be written as lambdas instead though, so the bit above would become something like:
std::remove_copy_if(a.begin(), a.end(), bind<int,
std::back_inserter(b),
[](int x) { return x < 5; });
This is not only shorter, but (at least once you're used to it) quite a bit simpler than using std::less and bind to put together a function. It won't generally make any difference in run-time efficiency -- a lambda is basically a "shorthand" way of generating a class template, so what it generates would end up pretty similar to the code using bind.

Variable arguments

Is there a non-boost way to create a function with variable arguments? I know the argument types number of arguments and they are usually less then 5, all of the same type.
I need to know if there is a way without supplying the argument count or ending the param list with null.
I know the argument types and they are usually less then 5.
If it is not going to be greater than 5, then simple overloads may do the work. Call the overload which accepts maximam number of arguments from all other overloads accepting less than 5 arguments, or define a worker (internal) function, call this from the overloads.
If possible, you could use default values for some of the parameters, if that helps reducing the number of overloaded functions.
In C++11, you could use variadic-template.
For up to 5 arguments all of the same type, simple overloads can do the trick.
For more generality, supporting any number of arguments of the same type, just pass a collection such as a std::vector.
For a C++03 technique to build such a collection on the fly in each call, see my other answer; for C++11, if you do not need to support Visual C++ you can use curly braces initializer lists as actual arguments.
Is cstdarg what you are looking for? This is the standard C++ way to generate functions with variable numbers of arguments.
You should be able achieve passing variable arguments using va_list.
You can:
if you're using C++11 you can use variadic templates, otherwise...
provide overloads
use arguments which default to some sentinel values you can recognise ala f(const T& v1 = missing, const T& v2 = missing, ...) { if (v5 != missing) ...
create a simple helper template that can optionally be constructed from the data type and has a bool to track whether it was
you may need to support types without default constructors by either using new/delete (simple and safe but slow) or having an aligned buffer you placement new into, manually destroy etc. (fiddly and easier to get wrong but faster)
some compilers have variadic macro support
if you're prepared to change the calling syntax a bit, you can use any number of things:
accept a vector (using a union or variant if the types differ)
accept an array (possibly using the template <size_t N> void f(T (&data)[N]) { ... } trick to have the compiler provide the array size to you automatically)
some kind of lhs object to which extra values can be supplied using an operator such as operator, or operator<<
As a general C++03 solution you can provide a setter that returns a reference to the object that it's called on, so that it can be called again. And again. And so on, called chaining.
It's the same scheme as iostreams use for operator<<.
E.g.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void foo( char const s[] )
{
cout << s << endl;
}
class StringBuilder
{
private:
string s_;
template< class Type >
string fastStringFrom( Type const& v )
{
stringstream stream;
stream << v;
return stream.str();
}
char const* fastStringFrom( char const* s )
{
return s;
}
string const& fastStringFrom( string const& s )
{
return s;
}
public:
template< class Type >
StringBuilder& operator<<( Type const& v )
{
s_ += fastStringFrom( v );
return *this; // Supports chaining.
}
operator string const& () const { return s_; }
operator char const* () const { return s_.c_str(); }
};
int main()
{
typedef StringBuilder S;
foo( S() << "6*7 = " << 6*7 << "." ); // Any number of arguments.
}
Instead of converting the argument values to text, you just do whatever it is that you need. For example, with a fixed set of possible types you can store the arguments in a collection.
If you do not need to support the Visual C++ compiler, then alternatively you can use a C++11 variadic template.