简体   繁体   English

function 模板参数和采用“自动”的 function 参数有什么区别?

[英]What's the difference between a function template argument and a function argument taking 'auto'?

I don't see the difference between these two, could someone tell me if there are differences?我看不出这两者之间有什么区别,有人可以告诉我是否有区别吗?

template <typename Arg1>
void templatedFuncAlsoTakingAutoArg(Arg1 arg1, auto arg2)
{
    // Both types are known at compile time for constexpr
    static constexpr decltype(arg1) variable1 = decltype(arg1)();
    static constexpr decltype(arg2) variable2 = decltype(arg2)();

    // And both types work with constexpr if so that invalid code
    // can appear within constexpr statements
    // If I pass in a double for arg1 or arg2 this still compiles
    if constexpr (std::is_integral_v<decltype(arg1)>)
    {
        arg1.non_existent_member = 7;
    }

    if constexpr (std::is_integral_v<decltype(arg1)>)
    {
        arg2.non_existent_member = 7;
    }
}

What I'm wondering is basically if it came down to writing a function what would be the difference if I wrote it like this:我想知道的是,如果它归结为写一个 function 如果我这样写会有什么区别:

template <typename Arg>
void likeThis(Arg arg){}

or:或者:

void orLikeThis(auto arg) {}

In the template version you have the advantage of being able to refer to the type directly, but in the 'auto' version you can always get the type with decltype anyway, right?在模板版本中,您具有能够直接引用类型的优势,但在“自动”版本中,您始终可以使用 decltype 获取类型,对吧? So what are the differences?那么有什么区别呢? Under the hood is the version that takes auto actually a template anyway, and is instantiated in the same way the compiler does templates?在引擎盖下是无论如何都采用 auto 实际上是模板的版本,并且以与编译器执行模板相同的方式实例化?

but in the 'auto' version you can always get the type with decltype anyway, right?但是在“自动”版本中,无论如何您总是可以使用 decltype 获取类型,对吗?

Not necessarily.不必要。 Conceptually doesn't change nothing, but the template / typename version is a little more flexible.概念上没有任何改变,但template / typename版本更灵活一些。

See the generic lambdas, introduced in C++14 using auto instead the template / typename syntax.请参阅在typename中引入的通用 lambda,使用auto而不是template /类型名语法。

In C++20 are introduced the template lambda because you can't do something as follows在 C++20 中引入了模板 lambda 因为你不能做如下的事情

[]<std::size_t ... Is>(std::index_sequence<Is...>)
 { return (Is + ...); }
 (std::make_index_sequence<10u>{});

in a simple way, using auto .以一种简单的方式,使用auto

EDIT: C++20 introduced the usage of auto as syntactic sugar for templates.编辑: C++20 引入了auto作为模板的语法糖的用法。 The below would only apply to former C++ standards以下仅适用于以前的 C++ 标准


It's important to remember, C++ is a statically typed language.重要的是要记住, C++ 是一种静态类型语言。

Using auto is like saying "figure out what type is suppose to go here and pretend like I wrote it out."使用auto就像是在说“弄清楚这里的 go 是什么类型,并假装我把它写出来了。” This means that a variable with auto still will resolve to be a particular type.这意味着具有auto的变量仍将解析为特定类型。 It does not mean that you can supply whatever type you want at runtime and expect it to figure it out, like you can with a dynamically typed language.并不意味着您可以在运行时提供您想要的任何类型并期望它能够解决,就像使用动态类型语言一样。

For that kind of functionality, you should use templates.对于这种功能,您应该使用模板。 But remember, you're still not supplying an arbitrary type at runtime and hoping that the code figures it out.但是请记住,您仍然没有在运行时提供任意类型,并希望代码能够解决这个问题。 At compile time, C++ needs to know what types you could use the function with, and then it will generate distinct versions of the function for those different types.在编译时,C++ 需要知道可以使用 function 的类型,然后它将为这些不同类型生成不同版本的 function。

For example, if you used auto :例如,如果您使用auto

orLikeThis("one");
orLikeThis(1.0f);

...would fail to compile. ...将无法编译。 The compiler has to assume that auto resolves to a single type, but since the code supplied both a string and a float, and now it can't resolve it to a single type.编译器必须假设auto解析为单一类型,但由于代码同时提供了字符串和浮点数,现在它无法将其解析为单一类型。

However,然而,

likeThis<string>("one")
likeThis<float>(1.1f)

Should compile.应该编译。 The compiler will create two different versions of the function to handle the different input types, but for convenience, you can simply provide a single function, and then just supply the type used.编译器将创建两个不同版本的 function 来处理不同的输入类型,但为方便起见,您可以简单地提供单个 function,然后只提供使用的类型。

So to answer your question of what the differences are, it comes down to how auto is syntactic sugar, and templates allow you to use multiple types in the "same" function.因此,要回答您关于差异是什么的问题,归结为auto是语法糖,模板允许您在“相同”function 中使用多种类型。


TLDR; TLDR; if you're looking to use multiple types, use a template;如果您希望使用多种类型,请使用模板; if you just want to avoid typing out the full type, then use auto .如果您只想避免输入完整类型,请使用auto (Or if you're using C++20, auto will work for both use cases). (或者,如果您使用的是 C++20, auto将适用于这两种用例)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 函数指针作为模板参数和函数签名作为模板参数之间的区别 - Difference between a function pointer as template argument and a function signature as template argument 使用std :: enable_if作为函数参数和模板参数有什么区别? - What is the difference between using std::enable_if as function argument vs template argument? 将 function 作为参数传递给另一个 function 的不同方式之间有什么区别? - What is the difference between different ways of passing a function as an argument to another function? auto in in function parameter list暗示模板参数 - auto in function parameter list implying template argument &#39;auto&#39; 作为函数参数的模板参数占位符 - 'auto' as a template argument placeholder for a function parameter 函数模板作为函数参数 - function template as a function argument 模板 function 采用数组参数 vs 重载 function 采用指针参数 - template function taking array argument vs overload function taking pointer argument 模板函数,将参数函数指针指向类方法 - template function taking argument function pointer to a class method 模板函数作为模板参数 - Template function as template argument 模板 function 作为模板参数 - A template function as a template argument
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM