I have the following code:
#define RETURNS(...) -> decltype((__VA_ARGS__)) { return (__VA_ARGS__); }
template <typename This, typename... Args>
auto fun(This &&this_, Args&&... args) RETURNS(this_.fun(std::forward<Args>(args)...))
For better or worse, this allows me to use fun(o, args...) and o.f(args...) interchangeably. The difficulty in using this comes when using an initializer list as an argument. E.g.
fun(obj, {1, 2, 3}); // Where obj.fun eventually takes a std::vector<int>.
This fails due to a substitution error, so Clang says. Note, obj.fun({1, 2, 3});
works.
As I understand it from other questions, this is because initializer lists don't always play nicely with template argument deduction.
The closest I have to my desired syntax is by making the initializer list more explicit. To avoid verbosity, I have the following:
template <typename T> std::initializer_list<T> il(std::initializer_list<T> &&li) { return li; }
fun(obj, il({1, 2, 3}));
Is there a way of getting my desired syntax or closer to it?
Clang's error report in my test program is:
subst.cpp:16:5: error: no matching function for call to 'fun'
fun(x, {1, 2, 3});
^~~
subst.cpp:6:6: note: candidate template ignored: substitution failure [with This
= X &, Args = <>]: too few arguments to function call, single argument 'v'
was not specified
auto fun(This &&this_, Args&&... args) RETURNS(this_.fun(std::forward<Args>(args)...))
^ ~