Boost logo

Boost Users :

Subject: Re: [Boost-users] function template with a universal reference to a specific type
From: Ireneusz Szcześniak (irek.szczesniak_at_[hidden])
Date: 2019-01-01 10:51:34


Thank you, Richard! That's very interesting. The function template
works as a dispatcher, so that we get T deduced.

The specialization can be partial since it is implemented as a struct,
and so your solution also works for templated types:

template <typename T>
struct Bar {};

template<typename T>
struct foo_op<Bar<T>>
{
     template<class Prefix, class Arg>
     void operator()(Prefix&& /*p*/, Arg&& /*bar*/) const
     {
       std::cout << "It's a Bar\n";
     }
};

Your solution is nifty, but also mind-boggling!

Best,
Irek

On 31.12.2018 13:04, Richard Hodges via Boost-users wrote:

> I think what you're asking is "how can I constrain a universal
> reference to be one primary type?"
>
> One way is to implement the general interface in terms of a
> specialised function object (this is my favourite).
>
> example:
>
> http://coliru.stacked-crooked.com/a/317cadb674e175b7
>
> This is my favourite because it allows selection of specialisations
> based on pattern matching rather than explicit overloads.
>
> #include <type_traits>
> #include <iostream>
>
> template<class T>
> struct foo_op
> {
>     template<class Prefix, class Arg>
>     void operator()(Prefix&& p, Arg&& /* a */) const
>     {
>         p();
>     }
> };
>
> template <typename T>
> auto
> foo(T &&t)
> {
>     auto op = foo_op<std::decay_t<T>>();
>     return op([funcname = __PRETTY_FUNCTION__]
>     {
>        std::cout << "Primary: " << funcname << std::endl;
>     }, std::forward<T>(t));
> }
>
>
> // then specialise
>
> struct Bar {};
>
> template<>
> struct foo_op<Bar>
> {
>     template<class Prefix, class Arg>
>     void operator()(Prefix&& /*p*/, Arg&& /*bar*/) const
>     {
>         std::cout << "It's a Bar\n";
>     }
> };
>
>
> int main()
> {
>     foo(6);  // default case
>     foo(Bar());  // bar case
> }
>
>
>
>
> On Sun, 30 Dec 2018 at 16:05, Ireneusz Szcześniak via Boost-users
> <boost-users_at_[hidden] <mailto:boost-users_at_[hidden]>> wrote:
>
> Hi,
>
> I'm writing to ask a C++ question, not specifically Boost-related,
> but
> this list is the best place I know.
>
> How can I write a function template, which has a parameter of the
> universal reference to a specific type?
>
> I can write a function template like this:
>
> template <typename T>
> void
> foo(T &&t)
> {
>    // The primary template implementation.
>    cout << "Primary: " << __PRETTY_FUNCTION__ << endl;
> }
>
> And so I can call this function with an expression of any value
> category, and any type, cv-qualified or not, like this:
>
> int
> main()
> {
>    foo(1);
>    int i = 1;
>    foo(i);
>    const int ci = 1;
>    foo(ci);
> }
>
> In my code I need to provide different implementations of foo for
> different types (and these types are templated).  How can I
> accomplish
> that?
>
>
> Best,
> Irek
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden] <mailto:Boost-users_at_[hidden]>
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>
>
>
> --
> Richard Hodges
> hodges.r_at_[hidden] <mailto:hodges.r_at_[hidden]>
> office: +442032898513
> home: +376841522
> mobile: +376380212 (this will be *expensive* outside Andorra!)
> skype: madmongo
> facebook: hodges.r
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net