Boost logo

Boost :

Subject: Re: [boost] Variadic append for std::string
From: Christof Donat (cd_at_[hidden])
Date: 2017-01-26 16:54:58


Hi,

Am 26.01.2017 19:44, schrieb Richard Hodges:
>> Is there a problem for ADL, when stringify_to() is a template on the
> string factory?
>
> Yes unfortunately. The template has the name `boost::stringify_to`
> regardless of the types. But if you go via a template functor object
> that
> uses ADL to find the free function, then the free function does not
> have to
> be a template function, and ADL will work as expected. In order to make
> the
> free function non-template you need to pass some trivial identifier
> from
> the function's namespace as an argument. So you'll need a tag type.
>
> so:
>
> namespace boost {
>
> template<class Tag>
> string_factory {
> using type = typename Tag::type;
> type operator()(joiner const& j) const {
> return stringify_to(Tag(), j);
> }
> };
>
> }

I think, we misunderstood each other. I want to have multiple string
factories, because the concat() string factory will work different than
the format() string factory. I could do that with virtual functions, but
that adds computational overhead at runtime. If I could templatize on
the string factory, while I overload on the object to write to, I can
resolve the string factory behavior at compile time and therefore get
rid of the virtual function call. Virtual function call are suboptimal
for the branch prediction of modern CPUs, and usually can not be
inlined.

This explanation suggests, that my approach should work:
http://en.cppreference.com/w/cpp/language/adl If there is a template
function with that name available by ordinary lookup, then Koenig lookup
kicks in and finds the correct overloaded template function.

namespace boost {
     template <typename StringFactory>
     std::string& stringify_to(StringFactory& f, std::string& t) {
         // ...
     }
     template <typename StringFactory>
     std::wstring& stringify_to(StringFactory& f, std::wstring& t) {
         // ...
     }

     class string_factory {
         public:
         // ...

         template <typename TargetT>
         auto to(TargetT& t) -> TargetT& {
             return stringify_to(*this, t);
         };
         // ...
     };
}

Here the ordinary lookup will find the standard overloads of
stringify_to template function. Then there is no syntax error any more,
and Koenig lookup will find the overloaded template function in the
target objects namespace as well:

namespace my_target {
     template <typename StringFactory>
     myTargetType& stringify_to(StringFactory& f, myTargetType& t) {
         // ...
     }
}

Now concat(...).to<myTargetType>() should find this template.

Did I misinterpret the explanation on cppreference, or is it wrong?

Christof


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk