Kode berikut mengkompilasi baik-baik saja dengan dentang-trunk dalam mode c ++ 17 tetapi istirahat dalam mode c ++ 2a (mendatang c ++ 20):
// Meta struct describing the result of a comparison
struct Meta {};
struct Foo {
Meta operator==(const Foo&) {return Meta{};}
Meta operator!=(const Foo&) {return Meta{};}
};
int main()
{
Meta res = (Foo{} != Foo{});
}
Itu juga mengkompilasi dengan gcc-trunk atau clang-9.0.0: https://godbolt.org/z/8GGT78
Kesalahan dengan dentang-batang dan -std=c++2a
:
<source>:12:19: error: use of overloaded operator '!=' is ambiguous (with operand types 'Foo' and 'Foo')
Meta res = (f != g);
~ ^ ~
<source>:6:10: note: candidate function
Meta operator!=(const Foo&) {return Meta{};}
^
<source>:5:10: note: candidate function
Meta operator==(const Foo&) {return Meta{};}
^
<source>:5:10: note: candidate function (with reversed parameter order)
Saya mengerti bahwa C + + 20 akan memungkinkan untuk hanya kelebihan operator==
dan kompiler akan secara otomatis menghasilkan operator!=
dengan meniadakan hasil operator==
. Sejauh yang saya mengerti, ini hanya berfungsi selama tipe kembalinya bool
.
Sumber masalahnya adalah bahwa di Eigen kita mendeklarasikan satu set operator ==
, !=
, <
, ... antara Array
objek atau Array
dan skalar, yang kembali (ekspresi) Array bool
(yang kemudian dapat diakses elemen-bijaksana, atau digunakan jika ). Misalnya,
#include <Eigen/Core>
int main()
{
Eigen::ArrayXd a(10);
a.setRandom();
return (a != 0.0).any();
}
Berbeda dengan contoh saya di atas ini bahkan gagal dengan gcc-trunk: https://godbolt.org/z/RWktKs . Saya belum berhasil menguranginya menjadi contoh non-Eigen, yang gagal di dentang-trunk dan gcc-trunk (contoh di atas cukup disederhanakan).
Laporan masalah terkait: https://gitlab.com/libeigen/eigen/issues/1833
Pertanyaan saya yang sebenarnya: Apakah ini benar-benar perubahan besar pada C ++ 20 (dan apakah ada kemungkinan untuk membebani operator pembanding untuk mengembalikan Meta-objek), atau apakah itu lebih cenderung berupa regresi dalam dentang / gcc?