对我来说,C ++模板使用了鸭子打字的想法,这是对的吗?这是否意味着模板类或方法中引用的所有泛型类型都是鸭类型?
答案 0 :(得分:70)
对我来说,C ++模板是duck typing的编译时版本。 编译器将编译例如只要你的鸭子等级 具有所有需要的类型,它将实例化一个类。
如果某些内容不正确(例如,复制构造函数丢失),则编译失败。 当你用一个函数调用一个函数时,真正的ducktyping中的对应物是失败的 非鸭型。在这里,它将在运行时发生。
答案 1 :(得分:13)
此外,由于模板参数推导,在C ++中您可以尝试传递任何旧对象,编译器将确定它是否可以实例化函数模板。
一个区别是在C ++中,如果参数不嘎嘎,那么编译器对象。在Python中,只有运行时对象(并且只有在实际调用函数时,如果代码中存在条件)。这是对象/类型所需接口性质的差异 - 在C ++中,模板要求特定表达式有效,要么不需要。在Python中,必要的有效表达式可以依赖于先前必需表达式的运行时值。所以在Python中你可以要求一个对象大声或悄悄地嘎嘎叫,如果它大声嘎嘎叫它也需要走路。在C ++中,您可以通过条件dynamic_cast
来实现,如果卷是编译时常量,您可以进行模板特化,但是您不能使用静态类型来说鸭子只需要走路quack_volume()
返回loud
。当然,在Python中,所需的接口可能并不是“必需的” - 如果不存在方法,则行为是抛出异常,如果发生这种情况,可能会记录并保证调用者的行为。
由您决定是否定义“duck typing”,以便这种差异意味着C ++没有它。
答案 2 :(得分:12)
对我来说,C ++模板使用了鸭子打字的想法,这是对的吗?
不,C ++模板用于实现通用代码。也就是说,如果您的代码可以使用多种类型,则不必为每种类型复制它。像std::vector
和std::list
这样的事情就是明显的例子。 C ++模板have been abused做其他事情,但通用性是最初的意图。
是否表示模板类或方法中引用的所有泛型类型 是鸭型?
不,它们只是“正常”类型,就像C ++中的其他类型一样。在模板实际实例化之前,它们才知道。
但是,模板可用于实现类似 duck typing的内容。迭代器就是一个例子。考虑这个功能:
template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result)
{
while (first!=last) *result++ = *first++;
return result;
}
请注意,copy
函数可以接受任何类型的参数,因为它实现了不等式运算符,解引用运算符和后缀增量运算符。这可能与你在C ++中获得的鸭子打字很接近。
答案 3 :(得分:4)
是的,有点 - 例如,如果类型X
具有AddRef()
,Release()
和QueryInterface()
方法以及适当的签名,则可以将其用作{{{1}的COM对象1}}模板类。但这并不是完整的鸭子类型 - 对参数仍然强制执行类型检查。
答案 4 :(得分:4)
不完全是。 Duck类型(动态类型样式)永远不会产生编译时类型错误,因为它们没有任何类型。使用模板,在实例化模板之前,您没有类型。一旦你这样做,变量有不同的类型,你确实会遇到编译时错误。
此外,对于duck类型,您可以将一个变量指向不同类型的对象,因为变量没有类型。这对模板来说是不可能的 - 一旦你实例化它们,变量只有一个特定的类型。
它们是相似的,因为约束是隐含的:只检查实际使用的特征。与多态指针相反,实际类型并不重要。
答案 5 :(得分:2)
不,这是一个不同的概念。 duck typing是一种查找动态类型容器类型的方法。 C ++模板不是动态类型,它们使用特定类型进行实例化。
答案 6 :(得分:1)