Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 何时将模板参数类型约束到具体类_C++_Templates - Fatal编程技术网

C++ 何时将模板参数类型约束到具体类

C++ 何时将模板参数类型约束到具体类,c++,templates,C++,Templates,如果我有一个可以为所有类型流定义的函数模板,例如 template<typename Stream> Stream& foo(Stream& stream) { return stream; } 模板 流与流(流与流) { 回流; } 将类型限制为具体类别是否有任何好处,例如 template<typename CharT, Traits> std::basic_istream<CharT, Traits>& foo(std

如果我有一个可以为所有类型
流定义的函数模板,例如

template<typename Stream>
Stream& foo(Stream& stream)
{
    return stream;
}
模板
流与流(流与流)
{
回流;
}
将类型限制为具体类别是否有任何好处,例如

template<typename CharT, Traits>
std::basic_istream<CharT, Traits>& foo(std::basic_istream<CharT, Traits>& stream)
{
    return stream;
}
模板
std::basic\u istream&foo(std::basic\u istream&stream)
{
回流;
}

或者,作为经验法则,函数/类模板是否应该尽可能通用,即使您考虑了特定的类型?

模板相对于限制类型的优势在于,如果给定类型支持您的函数需要对参数执行的操作,那么您的函数就可以工作,不再需要了。这也被称为“鸭子打字”

这是非常好的,特别是对于算术计算,然后自动工作的所有类型实现算术运算符

另一方面,当您期望类型的特定行为不能用“duck-typing”表示时,例如如果您的函数要求
a+=b
a=a+b
相同,您不希望出现这种情况的一个很好的示例(即严格类型的优点)(尽管在重载运算符时,这应该始终保持不变),或者在对类型调用函数时会发生特定的(并且想要的)副作用。但是,这样的“要求”可以(并且通常)在函数的文档(注释)中表达,例如(“
T::size()
预计将返回…”的数目)


一般的经验法则是:如果您事先知道要调用该函数的类型(例如,如果您已经有一个抽象超类),请使用特定类型。如果您希望类型集更“无限制”,请使用模板

在当前C++中,我们没有约束或概念,因此您以前的模板接口比一般需要的更通用,因为它也接受接口中不是流的类型。这会在调用函数模板并过载时容易产生歧义。
因此,尽可能使您的函数模板通用,但不要比需要的更通用。在这种情况下,您最好将精力放在其他方面。

如果您的模板函数仅在某些约束下工作,请将其放在文档中。您可以提供一个类似于
istream
的类,该类可以在您的原始情况下工作,但不适用于谢谢。如果我想创建一个对左值和右值都有效的函数,除了将第一个函数的签名更改为
Stream&&
?这对泛型类型有效吗?@user657267您可以编写一个
is_Stream
traits类,然后使用
Stream&
>使用SFINAE强制执行
is_stream::value
+1以避免出现歧义。如果
使用SFINAE和
enable_,则可以避免,但这远不容易编写(不包括阅读、调试、维护和审阅;使用SFINAE并不有趣)概念将帮助我们在未来的C++版本中,其中可以限制模板类型。