
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@lists.boost.org <mailto:boost-users@lists.boost.org>> 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@lists.boost.org <mailto:Boost-users@lists.boost.org> https://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Richard Hodges hodges.r@gmail.com <mailto:hodges.r@gmail.com> office: +442032898513 home: +376841522 mobile: +376380212 (this will be *expensive* outside Andorra!) skype: madmongo facebook: hodges.r
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users