我看不出这两个有什么不同,谁能告诉我有什么不同吗?
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;
}
}我想知道的是,如果归结为编写一个函数,如果我这样写,会有什么不同:
template <typename Arg>
void likeThis(Arg arg){}或者:
void orLikeThis(auto arg) {}在模板版本中,您可以直接引用类型,但在'auto‘版本中,无论如何都可以使用decltype获取类型,对吧?那么有什么不同呢?在引擎盖下,获取auto的版本实际上是一个模板,并且以与编译器实例化模板相同的方式实例化?
发布于 2021-05-27 04:12:26
但是在‘
’版本中,无论如何你都可以用decltype得到类型,对吧?
不一定。概念上不会改变任何东西,但是template/typename版本更灵活一些。
请参阅C++14中引入的通用lambda,使用auto代替template/typename语法。
在C++20中引入了模板lambda,因为您不能执行以下操作
[]<std::size_t ... Is>(std::index_sequence<Is...>)
{ return (Is + ...); }
(std::make_index_sequence<10u>{});以一种简单的方式,使用auto。
发布于 2021-06-08 02:58:51
编辑: C++20介绍了auto作为模板的语法糖的用法。以下内容仅适用于以前的C++标准
请务必记住,C++是一种静态类型的语言。
使用auto就像是说“弄清楚这里应该使用什么类型,然后假装它是我写出来的。”这意味着带有auto的变量仍将解析为特定类型。这并不意味着您可以在运行时提供您想要的任何类型,并期望它能像使用动态类型语言那样解决它。
对于这种功能,您应该使用模板。但请记住,您仍然没有在运行时提供任意类型,并希望代码能解决这个问题。在编译时,C++需要知道您可以将函数与哪些类型一起使用,然后它将为这些不同的类型生成函数的不同版本。
例如,如果您使用auto
orLikeThis("one");
orLikeThis(1.0f);...would无法编译。编译器必须假设auto解析为单一类型,但由于代码同时提供了字符串和浮点数,现在它不能将其解析为单一类型。
然而,
likeThis<string>("one")
likeThis<float>(1.1f)应该编译。编译器将创建两个不同版本的函数来处理不同的输入类型,但为了方便起见,您可以只提供一个函数,然后只提供所使用的类型。
因此,为了回答你的问题,区别是什么,它归结为auto是如何语法糖,并且模板允许您在“相同”函数中使用多种类型。
如果你想使用多种类型,使用一个模板;如果你只想避免输入完整的类型,那么使用auto。(或者,如果您使用的是C++20,那么auto将适用于这两种用例)。
https://stackoverflow.com/questions/67711972
复制相似问题