Author |
Topic |
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Jul 12 2017 : 04:57:34 AM
|
Hello,
when doing template functions with "universal references", I'd like the auto completion to suggest me the std::forward<T>(value) because 120% of the time it's what I want to write.
For example, lets consider the final result:
template<typename T>
void func1(T&& value)
{
func2(std::forward<T>(value));
} When I start to write:
func2(val The 2 suggestions would be:
value
std::forward<T>(value) It should also handle variadic parameters:
template<typename ...Ts>
void func1(Ts&&... values)
{
func2(std::forward<T>(values)...);
}
Regards. |
Edited by - tony.riviere on Jul 12 2017 05:00:04 AM |
|
feline
Whole Tomato Software
United Kingdom
19014 Posts |
Posted - Jul 12 2017 : 09:19:25 AM
|
What do you mean by "universal references"? I don't recognise this term. Do you mean the && on the function type?
Have you considered setting up a VA Snippet for this? My first instinct would be the snippet code:
std::forward($selected$)
with the shortcut "forw" and surround with set to "f"
this way the snippet can be triggered either by typing its shortcut, or by selecting the text / parameter list to pass and then pressing "f". |
zen is the art of being at one with the two'ness |
|
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Jul 12 2017 : 10:48:09 AM
|
"Universal references" are used in template functions to achieve perfect forward, meaning that the type T can be either a lvalue, const lvalue, rvalue, etc... depending on the caller.
So yes, basically it's when there is a '&&' after the type, but not always.
template<typename T>
void func1(T&& value); // T&& is a universal reference because there's a deduction type
void func2(Widget&& widget); // Here Widget&& is just an rvalue. Here is an article describing what are universal references https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers Note that inside std::forward<T>(value) the type T must be explicitly written, it's not just std::forward(value).
I could achieve something close using VA snippets:
std::forward<$type$>($selected$) So I write "value", then I select it and press '>' (option Surround with) then I just have to write the type of the variable in the $type$ placeholder. I works nicely. I didn't thought about using snippets.
However, is it possible given a selected variable to get automatically its type through VA snippets special variable so that here I don't need to write manually the type? |
|
|
feline
Whole Tomato Software
United Kingdom
19014 Posts |
Posted - Jul 12 2017 : 12:16:35 PM
|
That's a tad complex! Something I have not really caught up with yet :)
For now, you can replace $type$ with $clipboard$ if you are planning on doing several of these in a row. This does require copying the type before you start, but should make things quite a bit faster and easier.
A snippet variable for the template type would solve this problem, but what happens when the template has two types, or the type is defined? Consider these two examples:
template<typename T1, typename T2>
void funcTemplate(T1 paramOne, T2 paramTwo)
{
}
template<typename T = int>
void templateFuncLimited(T paramHere)
{
} I just want a clear description of what this snippet variable will do before putting in a feature request, since I can see this being useful in "normal" template classes as well. |
zen is the art of being at one with the two'ness |
|
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Jul 17 2017 : 09:49:50 AM
|
I think it comes really close to what $MethodArgs$ does. But instead of expanding to: param1, param2 It should expand to: std::forward<T1>(param1), std::forward<T2>(param2)
Example:
template<typename Obj, typename Fun, typename ...Args>
auto FuncWrapper(Fun&& fun, Obj&& obj, Args&&... args)
{
return std::invoke([insert snippet here]); // Initial state
return std::invoke(std::forward<Fun>(fun), std::forward<Obj>(obj), std::forward<Args>(args)...);
} To me, this snippet doesn't need to be "too" clever: it iterates on method's parameters, get the type of each parameter and expand it to std::forward<Type>(param). If it can avoid to write the forward for each parameters then it's far enough.
Also, I've just found out a bug with $MethodArgs$ and variadic parameter. Consider this method:
template<typename Fun, typename Obj, typename ...Args>
auto FuncWrapper(Fun fun, Obj obj, Args... args) When I use a snippet with $MethodArgs$ inside this function, it expands to obj, fun instead of obj, fun, args.... The variadic parameter isn't taken into account. |
|
|
feline
Whole Tomato Software
United Kingdom
19014 Posts |
Posted - Jul 17 2017 : 11:16:38 AM
|
We are considering allowing refactoring snippet reserved strings in non refactoring snippets:
case=3204
which would help here, but only if you are passing all of the functions parameters to the function call. As soon as you are passing only some of the function parameters you are going to get too many parameters, and possibly in the wrong order.
I am seeing the same problem with $MethodArgs$ here, thank you for the clear description:
case=109755 |
zen is the art of being at one with the two'ness |
|
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Jul 20 2017 : 10:11:15 AM
|
quote: Originally posted by feline
but only if you are passing all of the functions parameters to the function call.
Sounds good since most of the time we forward all parameters. Thanks. |
|
|
|
Topic |
|
|
|