我通过阅读通过示例加速 C++ 实用编程开始学习 C++,并被函数模板卡住了。我了解他们的工作......以及为什么他们有时可能有用。但我也觉得它们有点不雅,甚至让调用者感到困惑,让我解释一下。
书中首先定义了一个函数:
vector<string> split(string& s)
哪些 map "hello world"
到带有条目 hello
的 vector 和 word
.
然后,作者声称我们可以使我们的函数更加灵活,让调用者选择不同的容器(例如 list
而不是 vector ),为此,他们提出以下建议:
template <class Out> void split(const string& str, Out os)
我的问题是,
我怎么知道...作为调用者,Out 必须是
iterator
?它可以是任何东西。如果我发现它需要一个迭代器,我仍然不知道是哪一种..
input
output
forward
sequential
等等。
要弄清楚这些事情,我需要查看函数并查看迭代器中使用了哪些运算符(++
、>
、=
)。
作为该功能的“用户”,我应该关心 what
它确实...不是how
它做到了。
函数模板似乎鼓励使用较弱的类型。 在写这篇文章时,我意识到这个问题可能与 C++ 无关,更多的是因为我没有使用弱类型语言的经验,但我会让你来判断。
最佳答案
How do I know... as a caller that Out must be an iterator? it could technically be anything!
这是文档或代码作者的问题。良好的模板函数验证提供的类型是否符合预期。它可以做到,例如由几个 static_assert
确保Out
符合预期。标准库 <type_traits>
提供了许多测试,可以对类型进行检查。
或者您可以更详细地命名模板参数:
template <class OutputIterator> void split(const string& str, OutputIterator os)
现在没有人应该怀疑预期的类型。
Template functions seem to encourage dynamic typing.
C++ 中没有动态类型。所有模板参数都在编译时解析。编译器非常清楚 Out
是什么类型当它编译对 split
的每个调用时.
If I somehow figure out it takes an iterator, I still don't know which kind.. input output forward sequential etc.
再次,这是作者/文档的问题。如果您编写这样的函数,最好确保模板类型是您所期望的 static_assert
,但是测试是否存在运算符重载可能很困难。
关于c++ - C++ 函数模板是否鼓励弱类型化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60889590/