gpt4 book ai didi

c++ - 将引用显式传递到不期望引用的函数模板中会导致问题吗?

转载 作者:太空狗 更新时间:2023-10-29 19:42:24 25 4
gpt4 key购买 nike

a question关于传递采用以下函数模板,并使用引用字符串参数实例化它:

template <typename T>
void foo(T t) {}

答案当然是明确给出论点:

int main() {
std::string str("some huge text");
foo<std::string&>(str);
}

(顺便说一句,有关于使用推导和传递 C++0x 的 std::ref(str) 的建议,但这需要在函数内部使用 .get(),并且 OP 的要求是透明的。)

但是,IMO 毫无疑问函数模板的作者打算通过值传递参数,否则他会写:

template <typename T>
void foo(T& t) {}

(他有可能故意让任何一个成为可能,但出于某种原因,这对我来说似乎不太可能。)

  • 是否存在将引用传递给 foo<T> 的“合理”场景? , foo 的作者如果打算函数始终按值获取其参数,可能会导致问题吗?

  • 我正在寻找的答案很可能包含 foo 的函数体,其中使用了 T 的引用类型与为 T 使用值类型相比,会导致意想不到的/不受欢迎的语义.

最佳答案

考虑像这样编写算法是很常见的:

template <typename InputIterator>
void dosomething(InputIterator first, InputIterator last, otherparams) {
while (first != last) {
do the work;
++first;
}
}

这也是标准算法在 GCC 和旧的 SGI STL 中的实现方式。

如果 first 被引用,那么它将被修改,所以肯定有很多模板函数会在引用模板参数时“出错”。在此示例中,first 更改为等于 last 的值。在另一个实现中,或者在下一个版本中,它可能被复制而根本没有被修改。那是“意外/不受欢迎的语义”。

我不确定您是否称其为“问题”。这不是该函数的作者想要的行为,而且如果它通过引用传递(它不适用于标准算法),它可能没有记录 first 会发生什么。

对于标准算法,我认为它是 UB,所以调用者有错。标准规定模板参数应该是迭代器,而 T* 或某些库迭代器是迭代器类型,T* & 或 reference-to-library-iterator不是。

只要模板函数的作者清楚地记录了他们的模板参数的要求,我怀疑通常它会以与标准算法和迭代器相同的方式出现——引用类型不是有效的模板参数,因此调用者有错。在要求非常简单的情况下(几个具有指定行为的表达式),可能不排除引用类型,但同样只要函数不声明它 修改参数,但没有说明它如何修改参数,调用者应该考虑到因为没有记录参数是如何修改的,所以它是未指定的。如果他们使用引用类型调用函数,并对参数是否修改或修改方式感到惊讶,这又是调用者的错。

不过,我预计文档不足的函数有可能在出错时引发争议,因为有时它会依赖于相当仔细的阅读。

关于c++ - 将引用显式传递到不期望引用的函数模板中会导致问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6801843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com