Kode berikut tidak dikompilasi dengan gcc atau dentang.
template<class T>
class foo{};
template<class T>
class template_class_with_struct
{
void my_method() {
if(this->b.foo < 1);
};
struct bar
{
long foo;
} b;
};
Pesan kesalahan adalah
error: type/value mismatch at argument 1 in template parameter list for 'template<class T> class foo'
8 | if(this->b.foo < 1);
Kesalahan ini disebabkan oleh templat class foo. Saat menulis <= bukannya <1 juga mengkompilasi.
Ada petunjuk yang dihargai?
Tautan CompilerExplorer https://godbolt.org/z/v6Tygo
b.bar::foo
atau kurung ((this->b.foo) < 1
)Jawaban:
Di GCC, saya mengerti
Jadi, kompiler berpikir bahwa
foo
pada baris itu merujuk ke kelas difoo
atas dan mengharapkan argumen templat. Ini mirip dengan apa yang Anda lihat.Ketika Anda mengubahnya ke
<=
, yang tokenized oleh lexer sebagai token tunggal. Tahap selanjutnya bahkan tidak melihat a<
, jadi tidak bingung olehnya.Jika Anda mengubah kelas untuk tidak memiliki nama yang sama dengan yang lama
bar
, maka tidak memiliki masalah ini. @ Jarod42 juga memiliki saran dalam komentarnya untuk pertanyaan Anda (lebih banyak kualifikasi atau parens).Kompiler ditulis dalam tahap, di mana setiap tahap menerjemahkan kode ke representasi yang lebih baik untuk selanjutnya, dan setiap tahap dapat melakukan hal-hal yang semakin kompleks dengan representasi itu.
Pada awalnya, kompiler "lexes" kode, yang mengubah karakter individu dalam file menjadi aliran token - itu akan melihat baris ini sebagai sesuatu seperti
Dan kemudian sampai ke
foo
. Mungkin harus dilakukanTapi, bagi saya itu terlihat seperti ketika dilihat
foo
, terlihat di depan, melihat<
dan fakta yangfoo<class T>
ada dan mencoba membuat satu token darifoo< ...
tetapi kemudian tidak dapat menemukan>
untuk menyelesaikannya.Ini hanya dugaan - itu bisa menjadi tahap melewati lexer yang mencoba mencari nama dan dapat menggabungkan token. Bagaimanapun, berbagai penggunaan foo menipu itu.
sumber