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