2

In C++20 the auto keyword can be used for function input parameters. Is this a proper replacement for function templates and are there any practical differences to consider when deciding on which approach to take?

template <typename T>
void myFunction(T& arg)
{
    // ...
}

vs.

void myFunction(auto& arg)
{
    // ...
}

Related to and borrowed code from this old question.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
joaerl
  • 1,012
  • 1
  • 10
  • 21
  • you should use the `c++20` tag. And perhaps the other question should have the `c++11` tag added... – 463035818_is_not_an_ai Dec 13 '22 at 08:54
  • hm not sure about the other quesiton. One should check carefully the answers if they are correct also when restricting to c++11 – 463035818_is_not_an_ai Dec 13 '22 at 08:55
  • In this case, the `auto` syntax is an alternative means of defining a template function. The two are equivalent. – Peter Dec 13 '22 at 08:56
  • this answer https://stackoverflow.com/a/18135825/4117728 already considers `auto` function arguments and is basically already answering this question too – 463035818_is_not_an_ai Dec 13 '22 at 08:57
  • Dupe: [Is function with arguments of type `auto` implicitly converted to template?](https://stackoverflow.com/questions/74689307/is-function-with-arguments-of-type-auto-implicitly-converted-to-template?noredirect=1&lq=1) – Jason Dec 13 '22 at 09:04
  • A function with `auto` in parameter is actually a function template. See [this answer](https://stackoverflow.com/a/74514459/12002570) as a consequence of this fact. – Jason Dec 13 '22 at 09:05
  • 1
    a templated constructor is not a copy consturctor whether `template` or `auto` syntax is used. I do not undertand how the proposed duplicate is supposed to answer this question. It seems to be unrelated – 463035818_is_not_an_ai Dec 13 '22 at 09:14
  • The question which this is marked as a duplicate of might be related, but I cannot see how the question itself is a duplicate of that at all. If I found that question when looking for an answer to my question I would not even have read the answer. – joaerl Dec 13 '22 at 09:19
  • 1
    One difference is that in the first case you have a name for the type (`T`), should you need it, while in the second case it is more awkward `decltype(arg)`. Also, in `fun(T,T)` the parameters have the same type, while in `fun(auto,auto)` they can be different. – BoP Dec 13 '22 at 09:43
  • @JasonLiam There's a whole bunch of "functions with `auto` parameters that you are marking as duplicates of the same "can a template be a copy constructor" question, which while related, isn't *duplicate* – Caleth Dec 13 '22 at 09:46
  • @Caleth I see them as duplicates since the fundamental problem/issue is the same in all. Though in this question OP is asking about practical difference between two shown function(templates). So I am okay with this being reopened. – Jason Dec 13 '22 at 09:49
  • @JasonLiam *one* aspect of the question is the same. "can a (implicit) template be a copy constructor" is a duplicate of the "can a template be a copy constructor", with a note that "`auto` implies template" – Caleth Dec 13 '22 at 09:50
  • @Caleth Why are you concentrating on "copy ctor". The general theme(which is that `auto` implies template in function paramter) is the same. Just because one question is talking about "constructor" while other about "function" doesn't make the questions different. The fundamental reason is the same. – Jason Dec 13 '22 at 09:52

1 Answers1

4

For a function with one argument, there is no difference. With multiple arguments, auto is considered independently for each of them, i.e.

template <typename T>
void myBinaryFunction(T& arg1, T& arg2);

has no simple equivalent with auto, because arg1 and arg2 must deduce to the same type.

Similarly, non-type template parameters can't be auto

template <template <typename...> class Container, size_t N>
void convert(const std::array<int, N> & src, Container<int> & dest);

Nor can type parameters that are not present in the parameters

template <typename T>
T getById(int id);
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • But OP asked about one argument version so this should be a duplicate as the fundamental reason is the same(which is that there is no difference). You're talking about 2 argument version which OP hasn't asked. – Jason Dec 13 '22 at 09:50
  • 4
    @JasonLiam The *single example* in the OP is one argument, but they ask for differences in general. – Caleth Dec 13 '22 at 09:51
  • With return type SFINAE (of a trailing return) one could require the two `auto` to deduce the same type I guess, not sure exactly how (yet), but I think it is possible. – 463035818_is_not_an_ai Dec 13 '22 at 12:09
  • gcc even allows `void foo(std::vector)`... [Demo](https://godbolt.org/z/f11GEY77f) – Jarod42 Dec 13 '22 at 14:51
  • don't know why one would do it, but you can use 2 `auto` parameter and require they are the same. https://godbolt.org/z/fTEb31vbr. Though, your point still holds, not using `auto` for this is much simpler – 463035818_is_not_an_ai Dec 13 '22 at 17:07
  • 1
    @463035818_is_not_a_number and I think `template void myBinaryFunction(T& arg1, std::type_identity_t& arg2);` stumps even that. – Caleth Dec 13 '22 at 17:11
  • @463035818_is_not_a_number yes you can use trailing return type with enable_if to constrain the types to be the same. The answer to the op's question is yes, auto can 100% replace template syntax in the case of deduced argument types: `auto myBinaryFunction(auto& arg1, auto& arg2) -> std::enable_if_t< std::is_same_v, void>;` – Richard Hodges Dec 20 '22 at 14:47