あなたのコンパイラをとり、違いを確認するためにasmコードを出力させてください。あなたが最初の2つのバージョンが同じである見ることができるように
__Z13operatorLess1RK11screenPointS1_: ## @_Z13operatorLess1RK11screenPointS1_
push rbp
mov rbp, rsp
Ltmp2:
movss xmm0, dword ptr [rsi] ## xmm0 = mem[0],zero,zero,zero
mov al, 1
ucomiss xmm0, dword ptr [rdi]
ja LBB0_2
movss xmm0, dword ptr [rsi + 4] ## xmm0 = mem[0],zero,zero,zero
ucomiss xmm0, dword ptr [rdi + 4]
seta al
LBB0_2:
pop rbp
ret
.cfi_endproc
__Z13operatorLess2RK11screenPointS1_: ## @_Z13operatorLess2RK11screenPointS1_
.cfi_startproc
push rbp
mov rbp, rsp
Ltmp5:
movss xmm0, dword ptr [rsi] ## xmm0 = mem[0],zero,zero,zero
mov al, 1
ucomiss xmm0, dword ptr [rdi]
ja LBB1_2
movss xmm0, dword ptr [rsi + 4] ## xmm0 = mem[0],zero,zero,zero
ucomiss xmm0, dword ptr [rdi + 4]
seta al
LBB1_2:
pop rbp
ret
.cfi_endproc
__Z13operatorLess3RK11screenPointS1_: ## @_Z13operatorLess3RK11screenPointS1_
push rbp
mov rbp, rsp
Ltmp8:
movss xmm0, dword ptr [rdi] ## xmm0 = mem[0],zero,zero,zero
movss xmm1, dword ptr [rsi] ## xmm1 = mem[0],zero,zero,zero
mov al, 1
ucomiss xmm1, xmm0
ja LBB2_4
ucomiss xmm0, xmm1
jbe LBB2_3
xor eax, eax
pop rbp
ret
LBB2_3:
movss xmm0, dword ptr [rsi + 4] ## xmm0 = mem[0],zero,zero,zero
ucomiss xmm0, dword ptr [rdi + 4]
seta al
LBB2_4: ## %_ZNSt3__1ltIJRKfS2_EJS2_S2_EEEbRKNS_5tupleIJDpT_EEERKNS3_IJDpT0_EEE.exit
pop rbp
ret
.cfi_endproc
__Z13operatorLess4RK11screenPointS1_: ## @_Z13operatorLess4RK11screenPointS1_
.cfi_startproc
push rbp
mov rbp, rsp
Ltmp11:
movss xmm0, dword ptr [rdi] ## xmm0 = mem[0],zero,zero,zero
movss xmm1, dword ptr [rsi] ## xmm1 = mem[0],zero,zero,zero
mov al, 1
ucomiss xmm1, xmm0
ja LBB3_4
ucomiss xmm0, xmm1
jbe LBB3_3
xor eax, eax
pop rbp
ret
LBB3_3:
movss xmm0, dword ptr [rsi + 4] ## xmm0 = mem[0],zero,zero,zero
ucomiss xmm0, dword ptr [rdi + 4]
seta al
LBB3_4:
pop rbp
ret
.cfi_endproc
:
clang++ -S -masm=intel -std=c++11 -O2 a.cpp
利回りでコンパイルさ
#include <tuple>
__attribute__((noinline)) bool operatorLess1(const screenPoint& left, const screenPoint& right)
{
if (left.x < right.x) return true;
else return (left.y < right.y);
}
__attribute__((noinline)) bool operatorLess2(const screenPoint& left, const screenPoint& right)
{
return left.x < right.x || left.y < right.y;
}
__attribute__((noinline)) bool operatorLess3(const screenPoint& left, const screenPoint& right)
{
return std::tie(left.x, left.y) < std::tie(right.x, right.y);
}
__attribute__((noinline)) bool operatorLess4(const screenPoint& left, const screenPoint& right)
{
if (left.x < right.x) return true;
else if (left.x > right.x) return false;
else return (left.y < right.y);
}
:私のコンパイラ(打ち鳴らす)は二つのバージョンで同じ結果が得られます彼らはx
を比較するか、直接y
を比較します。 interjayで指摘されているように、代わりにstd::tie
のバージョンは、left.x > left.y
の完全な弱い順序を返します。実際のコードはoperatorLess4
と同じです。
誰かがかっこをすべて乱されています。 –
同じサイズの場合はどうなりますか?異なるサイズではないので、結果は他のものに行き、不正確になるでしょう。 – Charlie
最初のものは、辞書編集の比較を実装する 'std :: tie'と同じではありません。 'left.x'が' right.x'より大きい場合、 'std :: tie'は常にfalseを返します。 – juanchopanza