You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@thrift.apache.org by EY Tsai <ey...@comcast.net> on 2010/08/17 02:22:11 UTC

Any idea why build failed on cpp?

g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
/tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const':
petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const]+0x14): undefined reference to `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&) const'
/tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const':
petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
/tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const':
petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
collect2: ld returned 1 exit status
make: *** [client] Error 1

petclinic.thrif:

struct PetType {
   1: i32 id,
   2: string name
}

struct Specialty {
   1: i32 id,
   2: string name
}

struct Vet {
   1: i32 id,
   2: string firstName,
   3: string lastName,
   4: set<Specialty>  specialties
}

struct Visit {
   1: i32 id,
   2: i64 date,
   3: string description,
   4: i32 petFK
}

struct Pet {
   1: i32 id,
   2: string name
   3: string birthDate,
   4: PetType type,
   5: set<Visit>  visits,
   6: i32 ownerFK,
   7: i32 typeFK
}

struct Owner {
   1: i32 id,
   2: string firstName,
   3: string lastName
   4: i32 account,
   5: string address,
   6: string city,
   7: string telephone,
   8: set<Pet>  pets
}

service PetClinic {
   void putPetType(1: PetType petType),
   PetType getPetType(1: i32 id),
   void putPet(1: Pet pet),
   Pet getPet(1: i32 id),
   void putVisit(1: Visit visit),
   Visit getVisit(1: i32 id),
   void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
   set<Pet>  getOwnerPets(1: i32 ownerId),
   void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
   set<Visit>  getPetVisits(1: i32 petId),
   void putOwner(1: Owner owner),
   Owner getOwner(1: i32 id)
}

Thanks




Re: Any idea why build failed on cpp?

Posted by Bryan Duxbury <br...@rapleaf.com>.
I was unaware of this. I feel like there must be a way around this, but I
understand if there isn't one.

On Tue, Aug 17, 2010 at 11:28 AM, Rush Manbert <ru...@manbert.com> wrote:

> But if you generate a default comparator, then it can't be overridden for
> the generated class (unless I've forgotten some nuance of C++). You would
> need to edit the generated source files to get rid of the default
> implementation. Or just the comparator methods would need to be written to a
> separate C++ source file so it could be excluded from the build.
>
> I guess you could declare it as a virtual method and provide a default
> implementation, but then you would need to create a derived class in order
> to override the method. And I still wonder what a default implementation
> would do. Compare every data member, but if a data member is a struct go and
> compare its data members unless one of them is s struct, so go compare all
> of its data members... If we made the compiler provide some really dumb
> implementation that avoided what I just described, then you run the risk
> that people will just blindly use it and get themselves in trouble. Then the
> mailing list will get questions about strange runtime behavior, rather than
> link time errors. I know which type of question I'd rather try to answer.
> :-)
>
> I don't disagree with the "completeness" aspect, but in C++ the default
> implementation is very problematic.
>
> - Rush
>
> On Aug 17, 2010, at 10:14 AM, Bryan Duxbury wrote:
>
> > I'm pretty sure someone proposed generating default comparators in the
> past,
> > which is something I support from a completeness perspective.
> >
> > On Tue, Aug 17, 2010 at 10:10 AM, Rush Manbert <ru...@manbert.com> wrote:
> >
> >> Hi Basu,
> >>
> >> In truth, this seems like more of a documentation issue to me. And the
> OP
> >> could have found the answer with a goggle search, since this question
> came
> >> up and was answered at the end of July. (It had never come up before
> that.
> >> My personal Thrift mailing list starts on 4/25/08 and no one ever asked
> >> about this until now. Is that because Thrift usage is moving beyond the
> >> "expert user" group?)
> >>
> >> - Rush
> >>
> >> On Aug 16, 2010, at 6:15 PM, Basu Chaudhuri wrote:
> >>
> >>> Rush,
> >>>
> >>> This is a common mistake, especially for people new to C++ and/or STL.
> >> Would be possible to output a reminder or warning by default from the
> >> thrift-compiler to tell the user that he/she needs to create the
> >> corresponding definition for the operator.
> >>>
> >>> Basu
> >>>
> >>>
> >>> -----Original Message-----
> >>> From: Rush Manbert [mailto:rush@manbert.com]
> >>> Sent: Monday, August 16, 2010 5:40 PM
> >>> To: thrift-user@incubator.apache.org
> >>> Subject: Re: Any idea why build failed on cpp?
> >>>
> >>> Because the code generator declares but does not define operator<,
> which
> >> is required to insert into a set. You will need to implement those for
> Pet,
> >> Specialty, and Visit. I think you just need to write a file specifically
> for
> >> this that includes the petclinic_types.h file.
> >>>
> >>> - Rush
> >>>
> >>> On Aug 16, 2010, at 5:22 PM, EY Tsai wrote:
> >>>
> >>>>
> >>>> g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift
> >> -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift
> >> main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp
> >> gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
> >>>> /tmp/ccSEmUDT.o: In function
> >> `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty
> >> const&, tc_petclinic::Specialty const&) const':
> >>>>
> >>
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty
> >> const&, tc_petclinic::Specialty const&) const]+0x14): undefined
> reference to
> >> `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&)
> const'
> >>>> /tmp/ccSEmUDT.o: In function
> >> `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&,
> >> tc_petclinic::Visit const&) const':
> >>>>
> >>
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit
> >> const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to
> >> `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
> >>>> /tmp/ccSEmUDT.o: In function
> >> `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&,
> >> tc_petclinic::Pet const&) const':
> >>>>
> >>
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet
> >> const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to
> >> `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
> >>>> collect2: ld returned 1 exit status
> >>>> make: *** [client] Error 1
> >>>>
> >>>> petclinic.thrif:
> >>>>
> >>>> struct PetType {
> >>>> 1: i32 id,
> >>>> 2: string name
> >>>> }
> >>>>
> >>>> struct Specialty {
> >>>> 1: i32 id,
> >>>> 2: string name
> >>>> }
> >>>>
> >>>> struct Vet {
> >>>> 1: i32 id,
> >>>> 2: string firstName,
> >>>> 3: string lastName,
> >>>> 4: set<Specialty>  specialties
> >>>> }
> >>>>
> >>>> struct Visit {
> >>>> 1: i32 id,
> >>>> 2: i64 date,
> >>>> 3: string description,
> >>>> 4: i32 petFK
> >>>> }
> >>>>
> >>>> struct Pet {
> >>>> 1: i32 id,
> >>>> 2: string name
> >>>> 3: string birthDate,
> >>>> 4: PetType type,
> >>>> 5: set<Visit>  visits,
> >>>> 6: i32 ownerFK,
> >>>> 7: i32 typeFK
> >>>> }
> >>>>
> >>>> struct Owner {
> >>>> 1: i32 id,
> >>>> 2: string firstName,
> >>>> 3: string lastName
> >>>> 4: i32 account,
> >>>> 5: string address,
> >>>> 6: string city,
> >>>> 7: string telephone,
> >>>> 8: set<Pet>  pets
> >>>> }
> >>>>
> >>>> service PetClinic {
> >>>> void putPetType(1: PetType petType),
> >>>> PetType getPetType(1: i32 id),
> >>>> void putPet(1: Pet pet),
> >>>> Pet getPet(1: i32 id),
> >>>> void putVisit(1: Visit visit),
> >>>> Visit getVisit(1: i32 id),
> >>>> void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
> >>>> set<Pet>  getOwnerPets(1: i32 ownerId),
> >>>> void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
> >>>> set<Visit>  getPetVisits(1: i32 petId),
> >>>> void putOwner(1: Owner owner),
> >>>> Owner getOwner(1: i32 id)
> >>>> }
> >>>>
> >>>> Thanks
> >>>>
> >>>>
> >>
> >>
>
>

Re: Any idea why build failed on cpp?

Posted by Rush Manbert <ru...@manbert.com>.
But if you generate a default comparator, then it can't be overridden for the generated class (unless I've forgotten some nuance of C++). You would need to edit the generated source files to get rid of the default implementation. Or just the comparator methods would need to be written to a separate C++ source file so it could be excluded from the build.

I guess you could declare it as a virtual method and provide a default implementation, but then you would need to create a derived class in order to override the method. And I still wonder what a default implementation would do. Compare every data member, but if a data member is a struct go and compare its data members unless one of them is s struct, so go compare all of its data members... If we made the compiler provide some really dumb implementation that avoided what I just described, then you run the risk that people will just blindly use it and get themselves in trouble. Then the mailing list will get questions about strange runtime behavior, rather than link time errors. I know which type of question I'd rather try to answer. :-)

I don't disagree with the "completeness" aspect, but in C++ the default implementation is very problematic.

- Rush

On Aug 17, 2010, at 10:14 AM, Bryan Duxbury wrote:

> I'm pretty sure someone proposed generating default comparators in the past,
> which is something I support from a completeness perspective.
> 
> On Tue, Aug 17, 2010 at 10:10 AM, Rush Manbert <ru...@manbert.com> wrote:
> 
>> Hi Basu,
>> 
>> In truth, this seems like more of a documentation issue to me. And the OP
>> could have found the answer with a goggle search, since this question came
>> up and was answered at the end of July. (It had never come up before that.
>> My personal Thrift mailing list starts on 4/25/08 and no one ever asked
>> about this until now. Is that because Thrift usage is moving beyond the
>> "expert user" group?)
>> 
>> - Rush
>> 
>> On Aug 16, 2010, at 6:15 PM, Basu Chaudhuri wrote:
>> 
>>> Rush,
>>> 
>>> This is a common mistake, especially for people new to C++ and/or STL.
>> Would be possible to output a reminder or warning by default from the
>> thrift-compiler to tell the user that he/she needs to create the
>> corresponding definition for the operator.
>>> 
>>> Basu
>>> 
>>> 
>>> -----Original Message-----
>>> From: Rush Manbert [mailto:rush@manbert.com]
>>> Sent: Monday, August 16, 2010 5:40 PM
>>> To: thrift-user@incubator.apache.org
>>> Subject: Re: Any idea why build failed on cpp?
>>> 
>>> Because the code generator declares but does not define operator<, which
>> is required to insert into a set. You will need to implement those for Pet,
>> Specialty, and Visit. I think you just need to write a file specifically for
>> this that includes the petclinic_types.h file.
>>> 
>>> - Rush
>>> 
>>> On Aug 16, 2010, at 5:22 PM, EY Tsai wrote:
>>> 
>>>> 
>>>> g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift
>> -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift
>> main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp
>> gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
>>>> /tmp/ccSEmUDT.o: In function
>> `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty
>> const&, tc_petclinic::Specialty const&) const':
>>>> 
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty
>> const&, tc_petclinic::Specialty const&) const]+0x14): undefined reference to
>> `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&) const'
>>>> /tmp/ccSEmUDT.o: In function
>> `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&,
>> tc_petclinic::Visit const&) const':
>>>> 
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit
>> const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to
>> `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
>>>> /tmp/ccSEmUDT.o: In function
>> `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&,
>> tc_petclinic::Pet const&) const':
>>>> 
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet
>> const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to
>> `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
>>>> collect2: ld returned 1 exit status
>>>> make: *** [client] Error 1
>>>> 
>>>> petclinic.thrif:
>>>> 
>>>> struct PetType {
>>>> 1: i32 id,
>>>> 2: string name
>>>> }
>>>> 
>>>> struct Specialty {
>>>> 1: i32 id,
>>>> 2: string name
>>>> }
>>>> 
>>>> struct Vet {
>>>> 1: i32 id,
>>>> 2: string firstName,
>>>> 3: string lastName,
>>>> 4: set<Specialty>  specialties
>>>> }
>>>> 
>>>> struct Visit {
>>>> 1: i32 id,
>>>> 2: i64 date,
>>>> 3: string description,
>>>> 4: i32 petFK
>>>> }
>>>> 
>>>> struct Pet {
>>>> 1: i32 id,
>>>> 2: string name
>>>> 3: string birthDate,
>>>> 4: PetType type,
>>>> 5: set<Visit>  visits,
>>>> 6: i32 ownerFK,
>>>> 7: i32 typeFK
>>>> }
>>>> 
>>>> struct Owner {
>>>> 1: i32 id,
>>>> 2: string firstName,
>>>> 3: string lastName
>>>> 4: i32 account,
>>>> 5: string address,
>>>> 6: string city,
>>>> 7: string telephone,
>>>> 8: set<Pet>  pets
>>>> }
>>>> 
>>>> service PetClinic {
>>>> void putPetType(1: PetType petType),
>>>> PetType getPetType(1: i32 id),
>>>> void putPet(1: Pet pet),
>>>> Pet getPet(1: i32 id),
>>>> void putVisit(1: Visit visit),
>>>> Visit getVisit(1: i32 id),
>>>> void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
>>>> set<Pet>  getOwnerPets(1: i32 ownerId),
>>>> void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
>>>> set<Visit>  getPetVisits(1: i32 petId),
>>>> void putOwner(1: Owner owner),
>>>> Owner getOwner(1: i32 id)
>>>> }
>>>> 
>>>> Thanks
>>>> 
>>>> 
>> 
>> 


Re: Any idea why build failed on cpp?

Posted by Bryan Duxbury <br...@rapleaf.com>.
I'm pretty sure someone proposed generating default comparators in the past,
which is something I support from a completeness perspective.

On Tue, Aug 17, 2010 at 10:10 AM, Rush Manbert <ru...@manbert.com> wrote:

> Hi Basu,
>
> In truth, this seems like more of a documentation issue to me. And the OP
> could have found the answer with a goggle search, since this question came
> up and was answered at the end of July. (It had never come up before that.
> My personal Thrift mailing list starts on 4/25/08 and no one ever asked
> about this until now. Is that because Thrift usage is moving beyond the
> "expert user" group?)
>
> - Rush
>
> On Aug 16, 2010, at 6:15 PM, Basu Chaudhuri wrote:
>
> > Rush,
> >
> > This is a common mistake, especially for people new to C++ and/or STL.
> Would be possible to output a reminder or warning by default from the
> thrift-compiler to tell the user that he/she needs to create the
> corresponding definition for the operator.
> >
> > Basu
> >
> >
> > -----Original Message-----
> > From: Rush Manbert [mailto:rush@manbert.com]
> > Sent: Monday, August 16, 2010 5:40 PM
> > To: thrift-user@incubator.apache.org
> > Subject: Re: Any idea why build failed on cpp?
> >
> > Because the code generator declares but does not define operator<, which
> is required to insert into a set. You will need to implement those for Pet,
> Specialty, and Visit. I think you just need to write a file specifically for
> this that includes the petclinic_types.h file.
> >
> > - Rush
> >
> > On Aug 16, 2010, at 5:22 PM, EY Tsai wrote:
> >
> >>
> >> g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift
> -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift
> main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp
> gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
> >> /tmp/ccSEmUDT.o: In function
> `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty
> const&, tc_petclinic::Specialty const&) const':
> >>
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty
> const&, tc_petclinic::Specialty const&) const]+0x14): undefined reference to
> `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&) const'
> >> /tmp/ccSEmUDT.o: In function
> `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&,
> tc_petclinic::Visit const&) const':
> >>
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit
> const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to
> `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
> >> /tmp/ccSEmUDT.o: In function
> `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&,
> tc_petclinic::Pet const&) const':
> >>
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet
> const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to
> `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
> >> collect2: ld returned 1 exit status
> >> make: *** [client] Error 1
> >>
> >> petclinic.thrif:
> >>
> >> struct PetType {
> >> 1: i32 id,
> >> 2: string name
> >> }
> >>
> >> struct Specialty {
> >> 1: i32 id,
> >> 2: string name
> >> }
> >>
> >> struct Vet {
> >> 1: i32 id,
> >> 2: string firstName,
> >> 3: string lastName,
> >> 4: set<Specialty>  specialties
> >> }
> >>
> >> struct Visit {
> >> 1: i32 id,
> >> 2: i64 date,
> >> 3: string description,
> >> 4: i32 petFK
> >> }
> >>
> >> struct Pet {
> >> 1: i32 id,
> >> 2: string name
> >> 3: string birthDate,
> >> 4: PetType type,
> >> 5: set<Visit>  visits,
> >> 6: i32 ownerFK,
> >> 7: i32 typeFK
> >> }
> >>
> >> struct Owner {
> >> 1: i32 id,
> >> 2: string firstName,
> >> 3: string lastName
> >> 4: i32 account,
> >> 5: string address,
> >> 6: string city,
> >> 7: string telephone,
> >> 8: set<Pet>  pets
> >> }
> >>
> >> service PetClinic {
> >> void putPetType(1: PetType petType),
> >> PetType getPetType(1: i32 id),
> >> void putPet(1: Pet pet),
> >> Pet getPet(1: i32 id),
> >> void putVisit(1: Visit visit),
> >> Visit getVisit(1: i32 id),
> >> void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
> >> set<Pet>  getOwnerPets(1: i32 ownerId),
> >> void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
> >> set<Visit>  getPetVisits(1: i32 petId),
> >> void putOwner(1: Owner owner),
> >> Owner getOwner(1: i32 id)
> >> }
> >>
> >> Thanks
> >>
> >>
>
>

RE: Any idea why build failed on cpp?

Posted by Basu Chaudhuri <bc...@blueorigin.com>.
Hi Rush,

It's true, documentation would help immensely. I personally started using Thrift very recently and have to admit that's one thing that is lacking. 

The reason I mention it's a common mistake, is that I've seen it happen on numerous occasions, users, especially users new to STL, forget to implement the necessary operators when using set and map. It's not really a Thrift issue. My thought was that a warning could help the users getting moving faster. As you mentioned documentation would do the job.

Basu

-----Original Message-----
From: Rush Manbert [mailto:rush@manbert.com] 
Sent: Tuesday, August 17, 2010 10:10 AM
To: thrift-user@incubator.apache.org
Subject: Re: Any idea why build failed on cpp?

Hi Basu,

In truth, this seems like more of a documentation issue to me. And the OP could have found the answer with a goggle search, since this question came up and was answered at the end of July. (It had never come up before that. My personal Thrift mailing list starts on 4/25/08 and no one ever asked about this until now. Is that because Thrift usage is moving beyond the "expert user" group?)

- Rush

On Aug 16, 2010, at 6:15 PM, Basu Chaudhuri wrote:

> Rush,
> 
> This is a common mistake, especially for people new to C++ and/or STL. Would be possible to output a reminder or warning by default from the thrift-compiler to tell the user that he/she needs to create the corresponding definition for the operator.
> 
> Basu
> 
> 
> -----Original Message-----
> From: Rush Manbert [mailto:rush@manbert.com] 
> Sent: Monday, August 16, 2010 5:40 PM
> To: thrift-user@incubator.apache.org
> Subject: Re: Any idea why build failed on cpp?
> 
> Because the code generator declares but does not define operator<, which is required to insert into a set. You will need to implement those for Pet, Specialty, and Visit. I think you just need to write a file specifically for this that includes the petclinic_types.h file.
> 
> - Rush
> 
> On Aug 16, 2010, at 5:22 PM, EY Tsai wrote:
> 
>> 
>> g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
>> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const':
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const]+0x14): undefined reference to `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&) const'
>> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const':
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
>> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const':
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
>> collect2: ld returned 1 exit status
>> make: *** [client] Error 1
>> 
>> petclinic.thrif:
>> 
>> struct PetType {
>> 1: i32 id,
>> 2: string name
>> }
>> 
>> struct Specialty {
>> 1: i32 id,
>> 2: string name
>> }
>> 
>> struct Vet {
>> 1: i32 id,
>> 2: string firstName,
>> 3: string lastName,
>> 4: set<Specialty>  specialties
>> }
>> 
>> struct Visit {
>> 1: i32 id,
>> 2: i64 date,
>> 3: string description,
>> 4: i32 petFK
>> }
>> 
>> struct Pet {
>> 1: i32 id,
>> 2: string name
>> 3: string birthDate,
>> 4: PetType type,
>> 5: set<Visit>  visits,
>> 6: i32 ownerFK,
>> 7: i32 typeFK
>> }
>> 
>> struct Owner {
>> 1: i32 id,
>> 2: string firstName,
>> 3: string lastName
>> 4: i32 account,
>> 5: string address,
>> 6: string city,
>> 7: string telephone,
>> 8: set<Pet>  pets
>> }
>> 
>> service PetClinic {
>> void putPetType(1: PetType petType),
>> PetType getPetType(1: i32 id),
>> void putPet(1: Pet pet),
>> Pet getPet(1: i32 id),
>> void putVisit(1: Visit visit),
>> Visit getVisit(1: i32 id),
>> void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
>> set<Pet>  getOwnerPets(1: i32 ownerId),
>> void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
>> set<Visit>  getPetVisits(1: i32 petId),
>> void putOwner(1: Owner owner),
>> Owner getOwner(1: i32 id)
>> }
>> 
>> Thanks
>> 
>> 


Re: Any idea why build failed on cpp?

Posted by Rush Manbert <ru...@manbert.com>.
Hi Basu,

In truth, this seems like more of a documentation issue to me. And the OP could have found the answer with a goggle search, since this question came up and was answered at the end of July. (It had never come up before that. My personal Thrift mailing list starts on 4/25/08 and no one ever asked about this until now. Is that because Thrift usage is moving beyond the "expert user" group?)

- Rush

On Aug 16, 2010, at 6:15 PM, Basu Chaudhuri wrote:

> Rush,
> 
> This is a common mistake, especially for people new to C++ and/or STL. Would be possible to output a reminder or warning by default from the thrift-compiler to tell the user that he/she needs to create the corresponding definition for the operator.
> 
> Basu
> 
> 
> -----Original Message-----
> From: Rush Manbert [mailto:rush@manbert.com] 
> Sent: Monday, August 16, 2010 5:40 PM
> To: thrift-user@incubator.apache.org
> Subject: Re: Any idea why build failed on cpp?
> 
> Because the code generator declares but does not define operator<, which is required to insert into a set. You will need to implement those for Pet, Specialty, and Visit. I think you just need to write a file specifically for this that includes the petclinic_types.h file.
> 
> - Rush
> 
> On Aug 16, 2010, at 5:22 PM, EY Tsai wrote:
> 
>> 
>> g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
>> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const':
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const]+0x14): undefined reference to `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&) const'
>> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const':
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
>> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const':
>> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
>> collect2: ld returned 1 exit status
>> make: *** [client] Error 1
>> 
>> petclinic.thrif:
>> 
>> struct PetType {
>> 1: i32 id,
>> 2: string name
>> }
>> 
>> struct Specialty {
>> 1: i32 id,
>> 2: string name
>> }
>> 
>> struct Vet {
>> 1: i32 id,
>> 2: string firstName,
>> 3: string lastName,
>> 4: set<Specialty>  specialties
>> }
>> 
>> struct Visit {
>> 1: i32 id,
>> 2: i64 date,
>> 3: string description,
>> 4: i32 petFK
>> }
>> 
>> struct Pet {
>> 1: i32 id,
>> 2: string name
>> 3: string birthDate,
>> 4: PetType type,
>> 5: set<Visit>  visits,
>> 6: i32 ownerFK,
>> 7: i32 typeFK
>> }
>> 
>> struct Owner {
>> 1: i32 id,
>> 2: string firstName,
>> 3: string lastName
>> 4: i32 account,
>> 5: string address,
>> 6: string city,
>> 7: string telephone,
>> 8: set<Pet>  pets
>> }
>> 
>> service PetClinic {
>> void putPetType(1: PetType petType),
>> PetType getPetType(1: i32 id),
>> void putPet(1: Pet pet),
>> Pet getPet(1: i32 id),
>> void putVisit(1: Visit visit),
>> Visit getVisit(1: i32 id),
>> void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
>> set<Pet>  getOwnerPets(1: i32 ownerId),
>> void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
>> set<Visit>  getPetVisits(1: i32 petId),
>> void putOwner(1: Owner owner),
>> Owner getOwner(1: i32 id)
>> }
>> 
>> Thanks
>> 
>> 


RE: Any idea why build failed on cpp?

Posted by Basu Chaudhuri <bc...@blueorigin.com>.
Rush,

This is a common mistake, especially for people new to C++ and/or STL. Would be possible to output a reminder or warning by default from the thrift-compiler to tell the user that he/she needs to create the corresponding definition for the operator.

Basu
  

-----Original Message-----
From: Rush Manbert [mailto:rush@manbert.com] 
Sent: Monday, August 16, 2010 5:40 PM
To: thrift-user@incubator.apache.org
Subject: Re: Any idea why build failed on cpp?

Because the code generator declares but does not define operator<, which is required to insert into a set. You will need to implement those for Pet, Specialty, and Visit. I think you just need to write a file specifically for this that includes the petclinic_types.h file.

- Rush

On Aug 16, 2010, at 5:22 PM, EY Tsai wrote:

> 
> g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const':
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const]+0x14): undefined reference to `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&) const'
> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const':
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const':
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
> collect2: ld returned 1 exit status
> make: *** [client] Error 1
> 
> petclinic.thrif:
> 
> struct PetType {
>  1: i32 id,
>  2: string name
> }
> 
> struct Specialty {
>  1: i32 id,
>  2: string name
> }
> 
> struct Vet {
>  1: i32 id,
>  2: string firstName,
>  3: string lastName,
>  4: set<Specialty>  specialties
> }
> 
> struct Visit {
>  1: i32 id,
>  2: i64 date,
>  3: string description,
>  4: i32 petFK
> }
> 
> struct Pet {
>  1: i32 id,
>  2: string name
>  3: string birthDate,
>  4: PetType type,
>  5: set<Visit>  visits,
>  6: i32 ownerFK,
>  7: i32 typeFK
> }
> 
> struct Owner {
>  1: i32 id,
>  2: string firstName,
>  3: string lastName
>  4: i32 account,
>  5: string address,
>  6: string city,
>  7: string telephone,
>  8: set<Pet>  pets
> }
> 
> service PetClinic {
>  void putPetType(1: PetType petType),
>  PetType getPetType(1: i32 id),
>  void putPet(1: Pet pet),
>  Pet getPet(1: i32 id),
>  void putVisit(1: Visit visit),
>  Visit getVisit(1: i32 id),
>  void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
>  set<Pet>  getOwnerPets(1: i32 ownerId),
>  void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
>  set<Visit>  getPetVisits(1: i32 petId),
>  void putOwner(1: Owner owner),
>  Owner getOwner(1: i32 id)
> }
> 
> Thanks
> 
> 


Re: Any idea why build failed on cpp?

Posted by Rush Manbert <ru...@manbert.com>.
Because the code generator declares but does not define operator<, which is required to insert into a set. You will need to implement those for Pet, Specialty, and Visit. I think you just need to write a file specifically for this that includes the petclinic_types.h file.

- Rush

On Aug 16, 2010, at 5:22 PM, EY Tsai wrote:

> 
> g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const':
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const]+0x14): undefined reference to `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&) const'
> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const':
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
> /tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const':
> petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
> collect2: ld returned 1 exit status
> make: *** [client] Error 1
> 
> petclinic.thrif:
> 
> struct PetType {
>  1: i32 id,
>  2: string name
> }
> 
> struct Specialty {
>  1: i32 id,
>  2: string name
> }
> 
> struct Vet {
>  1: i32 id,
>  2: string firstName,
>  3: string lastName,
>  4: set<Specialty>  specialties
> }
> 
> struct Visit {
>  1: i32 id,
>  2: i64 date,
>  3: string description,
>  4: i32 petFK
> }
> 
> struct Pet {
>  1: i32 id,
>  2: string name
>  3: string birthDate,
>  4: PetType type,
>  5: set<Visit>  visits,
>  6: i32 ownerFK,
>  7: i32 typeFK
> }
> 
> struct Owner {
>  1: i32 id,
>  2: string firstName,
>  3: string lastName
>  4: i32 account,
>  5: string address,
>  6: string city,
>  7: string telephone,
>  8: set<Pet>  pets
> }
> 
> service PetClinic {
>  void putPetType(1: PetType petType),
>  PetType getPetType(1: i32 id),
>  void putPet(1: Pet pet),
>  Pet getPet(1: i32 id),
>  void putVisit(1: Visit visit),
>  Visit getVisit(1: i32 id),
>  void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
>  set<Pet>  getOwnerPets(1: i32 ownerId),
>  void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
>  set<Visit>  getPetVisits(1: i32 petId),
>  void putOwner(1: Owner owner),
>  Owner getOwner(1: i32 id)
> }
> 
> Thanks
> 
> 


RE: Any idea why build failed on cpp?

Posted by Mark Slee <ms...@facebook.com>.
It looks like you are using the set<> container on one of your types, which requires that you implement a comparator, since Thrift doesn't know how to provide one for you.

Since you are using sets, you must provide an implementation of this function in your source code:
tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const

-----Original Message-----
From: EY Tsai [mailto:ey.tsai@comcast.net] 
Sent: Monday, August 16, 2010 5:22 PM
To: thrift-user@incubator.apache.org
Subject: Any idea why build failed on cpp?


g++ -o CppClinicClient -I./gen-cpp -I/usr/local/include/thrift -I/usr/include/boost/  -I./ -L/usr/local/lib -lthrift main/CppClinicClient.cpp gen-cpp/petclinic_constants.cpp gen-cpp/petclinic_types.cpp  gen-cpp/PetClinic.cpp
/tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const':
petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic9SpecialtyEEclERKS1_S4_[std::less<tc_petclinic::Specialty>::operator()(tc_petclinic::Specialty const&, tc_petclinic::Specialty const&) const]+0x14): undefined reference to `tc_petclinic::Specialty::operator<(tc_petclinic::Specialty const&) const'
/tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const':
petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic5VisitEEclERKS1_S4_[std::less<tc_petclinic::Visit>::operator()(tc_petclinic::Visit const&, tc_petclinic::Visit const&) const]+0x14): undefined reference to `tc_petclinic::Visit::operator<(tc_petclinic::Visit const&) const'
/tmp/ccSEmUDT.o: In function `std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const':
petclinic_types.cpp:(.text._ZNKSt4lessIN12tc_petclinic3PetEEclERKS1_S4_[std::less<tc_petclinic::Pet>::operator()(tc_petclinic::Pet const&, tc_petclinic::Pet const&) const]+0x14): undefined reference to `tc_petclinic::Pet::operator<(tc_petclinic::Pet const&) const'
collect2: ld returned 1 exit status
make: *** [client] Error 1

petclinic.thrif:

struct PetType {
   1: i32 id,
   2: string name
}

struct Specialty {
   1: i32 id,
   2: string name
}

struct Vet {
   1: i32 id,
   2: string firstName,
   3: string lastName,
   4: set<Specialty>  specialties
}

struct Visit {
   1: i32 id,
   2: i64 date,
   3: string description,
   4: i32 petFK
}

struct Pet {
   1: i32 id,
   2: string name
   3: string birthDate,
   4: PetType type,
   5: set<Visit>  visits,
   6: i32 ownerFK,
   7: i32 typeFK
}

struct Owner {
   1: i32 id,
   2: string firstName,
   3: string lastName
   4: i32 account,
   5: string address,
   6: string city,
   7: string telephone,
   8: set<Pet>  pets
}

service PetClinic {
   void putPetType(1: PetType petType),
   PetType getPetType(1: i32 id),
   void putPet(1: Pet pet),
   Pet getPet(1: i32 id),
   void putVisit(1: Visit visit),
   Visit getVisit(1: i32 id),
   void putOwnerPets(1: i32 ownerId, 2: set<Pet>  pets),
   set<Pet>  getOwnerPets(1: i32 ownerId),
   void putPetVisits(1: i32 petId, 2: set<Visit>  visits),
   set<Visit>  getPetVisits(1: i32 petId),
   void putOwner(1: Owner owner),
   Owner getOwner(1: i32 id)
}

Thanks