让我们假设我按如下方式创建自己的向量类:
<template class T>
class Vector {
private:
void** ptr;
// More functions implementing the custom vector
public:
T& operator[](int iIndex) const {
return *(T*)ptr[iIndex];
}
T& Item(int iIndex) const {
return *(T*)ptr[iIndex];
}
}
假设我有一个Vector<someClass> v
。严格地说,在性能方面,这些对于访问向量的元素来说更快。
v.Item(i)
v[i]
答案 0 :(得分:7)
v[i]
仅仅是v.operator[](i)
的语法糖。
在性能方面没有差异,因为两个不同名称的功能在所有其他方面都没有相同的性能差异。
答案 1 :(得分:1)
要添加@ Bathsheba的回答,我做了一个快速测试,稍微更完整的虚拟Vector
实现:
template <class T>
class Vector {
private:
T* ptr;
public:
Vector(int size)
: ptr(new T[size])
{ }
~Vector()
{
delete[] ptr;
}
T& operator[](int iIndex) const {
return ptr[iIndex];
}
T& Item(int iIndex) const {
return ptr[iIndex];
}
};
int main()
{
Vector<int> v(5);
v[0] = 3;
v.Item(1) = 4;
}
使用g++ -S
,I get exactly identical assembly for both methods进行编译(在程序集输出中查找_ZNK6VectorIiEixEi
= Vector<int>::operator[](int) const
和_ZNK6VectorIiE4ItemEi
= Vector<int>::Item(int) const
)。这是预期的,因为operator[]()
和Item()
都是函数调用。操作符号只是语法糖。
答案 2 :(得分:1)
如评论中所说,在另一个回复中,没有任何区别。
运算符将生成对运算符的调用,并且由于这两个函数具有相同的代码,因此它们生成相同的程序集,从而产生完全相同的性能。
为了完整起见,我尝试使用clang 3.7来输入以下代码:
clang -O3 -g -S -emit-llvm main.cpp -o main.ll
编译:
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
entry:
%a.sroa.0.0.copyload = load double*, double** bitcast ([2 x double]* @_ZZ4mainE1a to double**), align 16, !dbg !57
%0 = load double, double* %a.sroa.0.0.copyload, align 8, !dbg !66, !tbaa !67
%call1 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), double %0), !dbg !72
%1 = load double, double* %a.sroa.0.0.copyload, align 8, !dbg !76, !tbaa !67
%call3 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), double %1), !dbg !78
ret i32 0, !dbg !79
}
它有效地生成完全相同的行:
{{1}}