1
votes

My task is to implement my own std::ref function. I know there is a reference_wrapper functor, which helps to the std::ref. But how could I implement these functions/classes. I think about the following:

template <class T>
struct myreference_wrapper{
    T& functor;
    myreference_wrapper(T& t):functor(t){}
    void operator()('parameter') {
        functor('parameter');
    };
};

template<class T>
myreference_wrapper<T> myref(T& t){
   myreference_wrapper<T> functor(t);
   return functor;
}

When we call myref, we can not use template parameters, because std::ref does not use template parameters. But when we call operator() we need to know its parameters, because we want to pass them on to the functor's operator() (I signed it with 'parameter'). How does std::ref do this without any template parameter?

1
You could try to specialize myreference_wrapper for Callable types. - Holt
Since when does std::ref not use template parameters? - user7881131
Why do you want to reinvent the wheel and not use std::ref? - zett42
Well, the best way to check how something in stl is implemented is... reading some implementation sources. Write std::ref in Visual Studio and press Alt + F12, for example. - Outshined
That's a great way to check, @Caribou, but not so great a way to understand. C++ standard library implementation files are often extremely complex and difficult to understand. It is not unreasonable to ask for a more lucid explanation on Stack Overflow. Although, checking the implementation first might have revealed that, in fact, std::ref does use template parameters. :-) - Cody Gray

1 Answers

2
votes

Template functions can deduce the template arguments from the types that the function is called with. For example:

template <class T> T min(T a, T b) {
    return a < b ? a : b;
}

When you call this function you don't need to specify the template arguments:

int x = min(1, 2);

The compiler looks at the types of the function arguments, sees that they are both int, and concludes that it needs to call min<int>.

Same thing for a call to your myref template function:

int i;
myref(i);

Again, the compiler looks at the type of the function argument, sees that it's int, and concludes that it needs to call myref<int>.

As an aside, the min function above can be a bit more complicated to use. min(1, 2.0) won't compile, because the two function argument types are different; one is int and one is double, so there is no T that exactly matches both. There are several possible solutions here. One is to rewrite the template function so that has two template type arguments instead of one: template <class T0, class T1> ??? min(T0, T1). That leads to a design problem: what's the right return type? Another solution is to change the calling code to pass arguments of the same type. And yet another is to give the template argument type explicitly: min<int>(1, 2.0). This code says to call min<int>, which takes two arguments of type int; the double will be converted to int, just as it would for a non-template function that takes two int values.