我一直在使用下面的print_vector
重载来打印出输入数组([1])的元素。
//////[1]///////
template<typename T>
void print_vector(T& vec) { // this function is for lagacy arrays in C/C++
// e.g. int x[3] = {1,2,3};
std::cout << "- print vector" << std::endl;
for (const auto& elem : vec) {
std::cout << elem << std::endl;
}
}
template<typename T>
void print_vector(std::vector<T>& vec) {
std::cout << "- print vector" << std::endl;
for (const auto& elem : vec) {
std::cout << elem << std::endl;
}
}
template<typename T>
void print_vector(thrust::host_vector<T>& vec) {
std::cout << "- print vector" << std::endl;
for (const auto& elem : vec) {
std::cout << elem << std::endl;
}
}
template<typename T>
void print_vector(thrust::device_vector<T>& vec) {
std::cout << "- print vector" << std::endl;
for (const auto& elem : vec) {
std::cout << elem << std::endl;
}
}
我喜欢这个的原因是,它似乎需要每个函数的“两个”类型-例如,std::vector
和T
的第二个。
但是我注意到下面的函数[2]可以单独为所有类型的输入执行所需的功能。
//////[2]///////
template<typename T>
void print_vector(T& vec) {
std::cout << "- print vector" << std::endl;
for (const auto& elem : vec) {
std::cout << elem << std::endl;
}
}
乍看之下,它似乎将两种类型过度压缩为一个T
,因此我认为这应该是类似于
//////[3]///////
template<typename T1, typename T2>
void print_vector(T1<T2>& vec) {
std::cout << "- print vector" << std::endl;
for (const auto& elem : vec) {
std::cout << elem << std::endl;
}
}
在C中使用[2]函数来表示[1]中的函数重载是标准的吗?还是说[2]工作正常是一种巧合?
事实上,我仍然感到困惑的是,ranged-for for (const auto& elem : vec) {}
适用于传统的C/C数组。当我搜索ranged-for时,我发现了这个句子-"defined as anything that you can iterate through—for example, std::vector, or any other C++ Standard Library sequence whose range is defined by a begin() and end()"
。虽然指针和迭代器非常相似,但它们并不相同,并且lagacy数组没有可以通过开始()和end()访问的“迭代器”,但仍然可以进行ranged-for工作。为什么?
已添加
感谢273 K,我觉得我越来越接近,但仍然不能得到一些积分。
例如,下面的代码在注解了vec.begin()
部分后可以正常工作。
template<typename T>
void print_vector(T& vec) {
//std::cout << vec.begin() << std::endl;
std::cout << "- print vector" << std::endl;
for (const auto& elem : vec) {
std::cout << elem << std::endl;
}
}
int main(void) {
int x[5] = {1,2,3,4,5};
print_vector(x);
return 0;
}
但是当我打开注解行时,我在编译过程中遇到了以下错误。
main.cu(12): error: expression must have class type but it has type "int *"
detected during instantiation of "void print_vector(T &) [with T=int [5]]"
所以,你能不能再解释一下你的话-“There are common std::开始(c)and std::end(c)for all containers and T(&)[N].”?
1条答案
按热度按时间shyt4zoc1#
这是另一种解释方式。基于范围的for循环的存在仅仅是为了让你在不需要索引、指针或迭代器的值的情况下编写更简单的循环。通过std::开始和std::end抽象的魔力,您的示例本质上与this code相同:
它看起来像是C和C的混合体。虽然C允许你创建对C风格数组的引用,但这些数组没有成员函数,因为这在C中并不是一件真正的事情。因此,当您尝试调用一个类型时,C样式数组会做它最擅长的事情,并隐式地转换为指针,但指针仍然不是类类型,因此编译失败。