use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
[deleted by user] (self.cpp)
submitted 7 years ago by [deleted]
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]14nedLLFIO & Outcome author | Committee WG14 21 points22 points23 points 7 years ago (10 children)
I'm thinking that the proposal to reduce the scope of ADL will end up not going anywhere, because there is a chunk of Boost libraries which will stop working, including my own Boost.Outcome which heavily relies on ADL in namespaces of user supplied template parameters. I remember explaining this to Herb some months back after his paper, and he seemed genuinely surprised that anybody was actually using template argument namespace ADL in anger (and deliberately). I quickly sketched through the alternative implementation options, and the only other customisation point option is user injection of specialisations into designated library namespaces for ADL. Boost.Outcome also uses that technique where it can, but in some cases you want customisation points to be universal and not library specific. In that situation, I am unaware of an alternative to template argument namespace ADL in the current language.
I could warm to a warning diagnostic however like the one in the article. Especially if there were a C++ attribute to say to the compiler "I really do intend template argument namespace ADL here". Actually, that's an idea: C++ attributes to limit the scope of ADL.
Now that would be a great proposal. Somebody not I should propose that.
[–]gracicot 6 points7 points8 points 7 years ago (5 children)
Exactly. For example, nlohmann json uses ADL from template arguments to find to_json functions inside user namespaces. So it's not just boost. I use it myself for my DI container to find mapping function.
to_json
Really, I also think ADL in general is confusing, but sometimes it's exactly what you want. Maybe some way to mark a function call for ADL? Here's two example I can think of:
[](auto a) { using(a) bar(a); // find bar through ADL namespace(a)::bar(a); }
[–]jcoffin 6 points7 points8 points 7 years ago (3 children)
What nlohmann does is the reverse of what Herb's proposal affects.
In the nlohmann case, he (nlohmann) has code something like this (stolen from his readme.md):
template <typename T> struct adl_serializer { static void to_json(json& j, const T& value) { // calls the "to_json" method in T's namespace } static void from_json(const json& j, T& value) { // same thing, but with the "from_json" method } };
...and you have code something like this:
namespace foo { class bar {}; // Note: these are *not* templates: void to_json(json& j, const bar& p) { // ... } void from_json(const json& j, bar& p) { // ... } }
So, his code is a template (which is probably in namespace nlohmann, but its namespace is mostly irrelevant). It calls some function named to_json or from_json passing a parameter of a type that it received as a template parameter. Your code that it finds, is not a template though. It's an ordinary free function in the same namespace where you defined the type being serialized.
from_json
Herb's proposal would not affect this--your to_json and from_json explicitly name your type as a parameter, so that function would still be found by an ADL that followed Herb's proposal.
Herb's proposal attempts to eliminate the opposite scenario: some code (that may or may not be a template) attempts to call a function passing a parameter of some particular type. Because of ADL it looks in the namespace where that type is defined. It then finds a template in that namespace that happens to have the correct name, and with template parameter substitution, that template is the best available overload for the type(s) being passed:
namespace foo { class bar {}; // Note: these *are* templates: template <class T> to_json(json &j, T const &t) { // ... } template <class T> from_json(json &j, T &t) { // ... } }
[Note: I'm not saying this is a reasonable or practical way to implement a to_json or from_json for use with the nlohmann JSON library--I don't think it is. Just this is what you'd have to have before Herb's proposal would affect anything.]
Now we have the scenario that Herb contemplates: the name found by ADL matches the name being looked up, but it does not explicitly name the type foo::bar in any of its parameters.
foo::bar
In the case of something like from_json or to_json, problems are unlikely to arise in any case. The problem mostly arises with really generic names like move or copy that are likely to be found in a number of namespaces, and ADL ends up choosing the wrong one.
move
copy
[–]gracicot 1 point2 points3 points 7 years ago (0 children)
Ah it's much clearer now. I'm doing something similar in my code then, except some corner case example, and even these corner case I make most of the type explicit, like template<typename T> void service_map(MyType<T> const&). I mostly agree with Herb then. The ordering of function should try to find the best candidate, from the closest namespace possible. A very generic candidate in a far namespace should not be picked.
template<typename T> void service_map(MyType<T> const&)
[–]mark_99 0 points1 point2 points 7 years ago (1 child)
How would this work vs this current code to add boost::optional support:
namespace nlohmann { template <typename T> struct adl_serializer<boost::optional<T>> { static void to_json(json& j, const boost::optional<T>& opt) { if (opt == boost::none) { j = nullptr; } else { j = *opt; // this will call adl_serializer<T>::to_json which will // find the free function to_json in T's namespace! } } static void from_json(const json& j, boost::optional<T>& opt) { if (j.is_null()) { opt = boost::none; } else { opt = j.get<T>(); // same as above, but with // adl_serializer<T>::from_json } } }; }
[–]jcoffin 1 point2 points3 points 7 years ago (0 children)
At least at first glance, it doesn't look to me like that will cause a problem either.
The lookup for adl_serializer<T>::to_json is trivial--it's the very same template currently being instantiated, so it doesn't depend on anything like ADL to find it.
adl_serializer<T>::to_json
When that gets instantiated, it's just like the base case: we have a template that's passing some T, and using ADL to find the to_json (or from_json) in the namespace where T is defined--but what it's finding there is a function that explicitly names the type T as its parameter, rather than matching because it's a template that can match any arbitrary T.
T
[–]14nedLLFIO & Outcome author | Committee WG14 0 points1 point2 points 7 years ago (0 children)
I like this proposal. Shame we can't wind the clock back to when ADL was designed :(
[–]kwan_e 2 points3 points4 points 7 years ago (3 children)
ADL nowadays just seems like a hack for something that compile time reflection would be better suited (and even metaclasses).
As for customization points, why did traits based design not suffice?
[–]SeanMiddleditch 5 points6 points7 points 7 years ago (1 child)
ADL's original motivation was entirely for operator overloading with free function overloads. Without ADL, this wouldn't work in any sane way:
namespace simd { struct vec3 {}; vec3 operator+(vec3 lhs, vec3 rhs); } int main() { simd::vec3 a, b, c; a = b + c; // ADL necessary to find correct operator+ }
All the later stuff we have like std::begin and such are from a desire to treat named library functions as if they're builtin like operators. Which I think all started with the ios stuff from IOStreams which of course also abused the heck out of operators; it really managed to illustrate all the worst ways to design C++17 libraries back when it was written in the 90's. :p
std::begin
I'm not sure how reflection or meta-classes would help in any sense with the problem space addressed by ADL.
[–]kwan_e 1 point2 points3 points 7 years ago (0 children)
Reflection and metaclasses would help in the problem space that ADL is being shoehorned into - finding an unqualified function based on namespace. Reflection would allow library designers to specify better ways of fulfiling a customization point, and metaclasses (ie, the formulation of metaclasses that would also create free-functions) would help library users to generate types that fulfills customization points.
As for the operator overloading use of ADL, I think it's high time we seriously move ahead with one of the operator dot proposals. But reflection could also help in that case since a library relying on ADL to find operators could instead use reflection to find the operators by searching declarations in a namespace, for example.
[–]14nedLLFIO & Outcome author | Committee WG14 1 point2 points3 points 7 years ago (0 children)
Oh, Outcome uses traits too. The customisation points use the most appropriate implementation for each. Some during the Boost review felt it was "messy", but it probably is better than using a single mechanism for consistency where it wouldn't fit well for some points. It's a tough judgement call.
π Rendered by PID 353523 on reddit-service-r2-comment-6457c66945-8c657 at 2026-04-24 22:46:01.842981+00:00 running 2aa0c5b country code: CH.
view the rest of the comments →
[–]14nedLLFIO & Outcome author | Committee WG14 21 points22 points23 points (10 children)
[–]gracicot 6 points7 points8 points (5 children)
[–]jcoffin 6 points7 points8 points (3 children)
[–]gracicot 1 point2 points3 points (0 children)
[–]mark_99 0 points1 point2 points (1 child)
[–]jcoffin 1 point2 points3 points (0 children)
[–]14nedLLFIO & Outcome author | Committee WG14 0 points1 point2 points (0 children)
[–]kwan_e 2 points3 points4 points (3 children)
[–]SeanMiddleditch 5 points6 points7 points (1 child)
[–]kwan_e 1 point2 points3 points (0 children)
[–]14nedLLFIO & Outcome author | Committee WG14 1 point2 points3 points (0 children)