假设我有两个std::vector
:
std::vector<int> v_int(1000);
std::vector<T> v_T(1000); // Where T is copy-costy type
如果我需要在不需要编辑我可能使用的项目的情况下(透明地)循环它们:
for(const auto item:v_int){
//...
}
for(const auto& item:v_T){ //Note &
//...
}
使用const auto item:v_T
进行迭代太糟糕了,因为每次迭代都会执行一次复制。但是,使用const auto& item:v_int
并非最佳,但并非那么糟糕。因此,如果我需要一个处理它们的代码,我以前使用const auto& item:v
。
问题:是否有一种通用的方法来编写for循环,它将使用两者的最佳声明?类似的东西:
template <typename T>
void iterate(const std::vector<T> v){
for(const auto/*&*/ item:v){ // activate & if T is not elementary type
//...
}
}
答案 0 :(得分:10)
您可以使用标准类型特征执行此操作:
template <typename T>
using select_type = std::conditional_t<std::is_fundamental<T>::value,
const T, const T&>;
template <typename T>
void iterate(const std::vector<T> v){
for(select_type<T> item:v){ // activate & if T is not elementary type
//...
}
}
然而,我质疑这样做的智慧。它只会使代码混乱,因为它不会产生任何影响。
答案 1 :(得分:4)
当您不在乎时使用server = sshtunnel.open_tunnel(ip, ssh_username="test",
ssh_password="test",
remote_bind_address=("1.2.3.4", 23))
try:
with server:
print "SSH connected"
except KeyboardInterrupt:
print "Pressed Ctrl-C"
server._stop_transport()
print "SSH Closed"
。如果必须保证未编辑,请使用auto&&
。
引用是别名,并且在像循环这样的直接上下文中,优化不存在是微不足道的,尤其是在从未修改过值的情况下。
将引用通过编译单元边界传递给函数时存在一些困难,这就是为什么有时会建议按值auto const&
而不是int
,但这不适用于此。
答案 2 :(得分:0)
我不是template
区域的专家,但我觉得困扰你的是char
如果&
副本只复制一个字节,而使用sizeof(char*)
则会复制{{1} }} bytes。
我想到的是使用sizeof(T)
。
在这种情况下,您可以使用
if (sizeof(T) >= sizeof(void*))
// use '&'
else
// don't use '&'
因为在编译时评估sizeof
,所以编译器将优化此if
分支。
答案 3 :(得分:0)
就个人而言,我只会使用const auto&amp;对于每种情况,因为除非您需要在紧密循环中处理一些非常大的数据集,否则开销可以忽略不计。
获取所需内容的方法可能是为迭代方法实现模板特化:
#include <iostream>
#include <string>
#include <vector>
template <typename T>
void iterate(const std::vector<T>& v){
for(const auto& item:v){
std::cout << item << std::endl;
}
}
template <>
void iterate(const std::vector<int>& v){
for(const auto item:v){
std::cout << "[" << item << "]" << std::endl;
}
}
int main()
{
std::vector<std::string> strings = { "foo", "bar" };
std::vector<int> numbers = { 1, 2 };
iterate(strings);
iterate(numbers);
}
注意:您更有可能看到从构建向量的副本到迭代函数的性能损失:)