繁体   English   中英

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

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

我看不出这两者之间有什么区别,有人可以告诉我是否有区别吗?

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;
    }
}

我想知道的是,如果它归结为写一个 function 如果我这样写会有什么区别:

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

或者:

void orLikeThis(auto arg) {}

在模板版本中,您具有能够直接引用类型的优势,但在“自动”版本中,您始终可以使用 decltype 获取类型,对吧? 那么有什么区别呢? 在引擎盖下是无论如何都采用 auto 实际上是模板的版本,并且以与编译器执行模板相同的方式实例化?

但是在“自动”版本中,无论如何您总是可以使用 decltype 获取类型,对吗?

不必要。 概念上没有任何改变,但template / typename版本更灵活一些。

请参阅在typename中引入的通用 lambda,使用auto而不是template /类型名语法。

在 C++20 中引入了模板 lambda 因为你不能做如下的事情

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

以一种简单的方式,使用auto

编辑: C++20 引入了auto作为模板的语法糖的用法。 以下仅适用于以前的 C++ 标准


重要的是要记住, C++ 是一种静态类型语言。

使用auto就像是在说“弄清楚这里的 go 是什么类型,并假装我把它写出来了。” 这意味着具有auto的变量仍将解析为特定类型。 并不意味着您可以在运行时提供您想要的任何类型并期望它能够解决,就像使用动态类型语言一样。

对于这种功能,您应该使用模板。 但是请记住,您仍然没有在运行时提供任意类型,并希望代码能够解决这个问题。 在编译时,C++ 需要知道可以使用 function 的类型,然后它将为这些不同类型生成不同版本的 function。

例如,如果您使用auto

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

...将无法编译。 编译器必须假设auto解析为单一类型,但由于代码同时提供了字符串和浮点数,现在它无法将其解析为单一类型。

然而,

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

应该编译。 编译器将创建两个不同版本的 function 来处理不同的输入类型,但为方便起见,您可以简单地提供单个 function,然后只提供使用的类型。

因此,要回答您关于差异是什么的问题,归结为auto是语法糖,模板允许您在“相同”function 中使用多种类型。


TLDR; 如果您希望使用多种类型,请使用模板; 如果您只想避免输入完整类型,请使用auto (或者,如果您使用的是 C++20, auto将适用于这两种用例)。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM