c++ Compiler could not generate operator= for class - c++

This code:
struct TToken
{
UnicodeString &DBIDs;
std::vector<TToken> T;
TToken(UnicodeString &DI) : DBIDs(DI) {}
void Append(void) {T.push_back(TToken(DBIDs));}
};
UnicodeString DI="25,40,55";
TToken T(DI);
if (T.DBIDs==DI) // if I comment out this comparison it works fine
....
generates the above compiler error (I'm using C++Builder 10.1 Berlin).
If I change the UnicodeString reference to a pointer, it all works as expected. Does anyone know why the reference generates the error?
By the way, is there an easier way of making DBIDs available to every created vector element instead of passing a pointer/reference all the way down the line? A static member is no good, and I did look at template expressions, but couldn't get an acceptable answer.

Related

Warning unused variable using typeid

I have written a small wrapper for typeinfo to get the typecode of a variable at compile time more easily:
template<typename DataType>
class TypeInfo
{
public:
static const char* typecode()
{
DataType TypedVariable = 0;
const char* code = typeid(TypedVariable).name();
return(code);
};
};
I use it like this:
const char* code = TypeInfo<float>::typecode();
It compiles perfectly fine and works as expected, but I am getting the warning
src/common.hh(153): warning: variable "TypedVariable" was set but never used
detected during:
instantiation of "char TypeInfo<DataType>::typecode() [with DataType=r32]"
...
I am wondering why "calling" typeid() on a variable does not count as using it. I know that it is a defined keyword, but still I am irritated that getting the type of a variable does not count as using it.
The compilation is done using nvcc of CUDA 9.2. Maybe it is a CUDA specific thing?
Thanks for any help :)
//edit:
I made a mistake by not returning the full char* because I use only normal types! Thanks for making me aware of the typo! I also added the template definition. I forgot to copy that over!
Because you don't use the value of TypedVariable. You just use its type (and you can get it's type by rewriting your initialization as:
char const * const code = typeid(DataType).name();

How to pass a TListstring by reference wrapped into a Class?

File .h:
class A{
public:
TStringList &tsl;
A(TStringList &arg) : tsl(arg) {}
}
void foo(A& dto);
File cpp:
void foo(A& dto);
{
dto.tsl.String[0] = "AAA";
}
Use:
TStringList *a= new TStringList();
......(some code )......
A dtoArg=A(*a);
a.String[0]="BBB";
foo(dtoArg);
Printf("first element now is %s",a.String[0] );
Even if the project compiles and all seems fine at runtime, the behavior is not the expected one. The output is BBB and not AAA as expected. This means that the TStrngList is passed by value and not by reference.
So, how to pass the TString list by reference. I won't copy the TSringList when it is passed to function foo().
I don't know how your TStringList is defined, but when I replace it witha mock class like
struct TStringList {
TStringList() { String.resize(10); }
vector<string> String;
};
and correct your typos like a.String[0] to a->String[0], then it works fine for me.
Whats the return type of operator [] for the TStringList?
I believe the ......(some code )...... might be worth digging into?!
Please make sure you submit a complete and reproducible test case next time.
Sorry all,
all works fine. The error was in my unit test and not in the tested code.....
So, this topic can be closed or removed. The TStringList has no problem to be passed by reference.

boost::date_time with C++11 fails to compile

I recently upgraded my Intel C++ compiler from v13.0.1 (aka 2013) to v14.0.0 (aka 2013 sp1). It looks as though the standard libraries that it uses have become more C++11 compliant. As part of that, std::locale::facet was changed from:
class locale::facet {
protected:
explicit facet (size_t refs = 0);
virtual ~facet();
private:
facet (const facet&); // not defined
void operator= (const facet&); // not defined
}
To:
class locale::facet {
protected:
explicit facet (size_t refs = 0);
virtual ~facet();
facet (const facet&) = delete;
void operator= (const facet&) = delete;
}
The key piece being the use of = delete to make it non-copyable. (Thanks to http://www.cplusplus.com/reference/locale/locale/facet/ for that side-by-side comparison.)
However, boost/date_time/date_facet.hpp uses this:
class date_facet : public std::locale::facet {
That's unchanged in both boost v1.48.0 and v1.54.0 (the two that I have installed in my environment).
date_facet doesn't appear to declare any copy constructor or operator=.
In my own code, I am using it to make class static constants to hold a time format. So in a header file I have this as part of a class definition:
static const boost::local_time::local_time_facet _MYFACET;
And in the matching source file I have this:
const boost::local_time::local_time_facet MyClass::_MYFACET = boost::local_time::local_time_facet("%Y/%m/%d %H:%M:%S.%f");
This code has worked for years and is unchanged.
Now, when I try to compile I get this error:
/usr/include/boost/date_time/date_facet.hpp(49): error #373: "std::locale::facet::facet(const std::locale::facet &)" (declared at line 409 of "/usr/include/c++/4.4.6/bits/locale_classes.h") is inaccessible
class date_facet : public std::locale::facet {
^
compilation aborted for MyFile.cpp (code 2)
Googling hasn't turned up anyone else talking about this problem, which makes me think that I'm just doing something stupid.
Anyone else encountered this?
Anyone have a solution?
My only idea is to explicitly add an = delete declaration to date_facet. I'll try that and supply my own answer if it works. But I really have no idea. (Edit: this idea was a failure, so don't try it.)
The reason for your troubles is that the =delete fires at compile-time in case you try to use it. Your existing code worked because the copy-constructor was required to be accessible (which is was), but it was optimized away by copy elision. The linker, who was supposed to catch the use of the copy-ctor therefore never complained and all seemed fine. That said, you might simply change your code to
const boost::local_time::local_time_facet MyClass::_MYFACET("%Y/%m/%d %H:%M:%S.%f");
and remove the need to an accessible (or even existing) copy-ctor.
Why can not you write simply
const boost::local_time::local_time_facet MyClass::_MYFACET("%Y/%m/%d %H:%M:%S.%f");
P.S. It seems that the early version of the compiler had a bug.:)

C++ Struct initialisation problem

This c++ code is working fine , however memory validator says that I am using a deleted pointer in:
grf->filePath = fname; Do you have any idea why ? Thank you.
Dirloader.h
// Other code
class CDirLoader
{
public:
struct TKnownGRF
{
std::string filePath;
DWORD encodingType;
DWORD userDataLen;
char *userData;
};
// Other Code
CDirLoader();
virtual ~CDirLoader();
Dirloader.cpp
// Other code
void CDirLoader::AddGroupFile(const std::string& _fname)
{
// Other code including std::string fname = _fname;
TKnownGRF *grf = new TKnownGRF;
grf->filePath = fname;
delete grf; // Just for testing purposes
P.S.: This is only an code extract. Of course if I define a struct TKnownGRF inside .cpp and use it as an actual object, gfr.filepath = something, instead of pointer grf->filepath=something, than it is ok, but I do need to have it inside *.h in CDirLoader class, due to many other vector allocations.
Since the function returns void
void CDirLoader::AddGroupFile(const std::string& _fname)
the question is what are you going to do with grf?
Are you going to delete it? If so, then, why do a new? you can just declare a TKnownGRF variable on the stack! In that case, _fname is not contributing to the logic of this method.
I guess that the class CDirLoader has a member variable of type TKnownGRF, say grf_, and that need to be used in the AddsGroupFile() method, e.g.:
grf_.filepath = _fname;
Does this happen to be using an older version of STL, say, VC6, and running multithreaded? Older versions of STL's string class used a reference counted copy on write implementation, which didn't really work in a multithreaded environment. See this KB article on VC 6.
Or, it's also possible that you are looking at the wrong problem. If you call std::string::c_str() and cache the result at all, the cached result would probably be invalidated when you modified the original string. There are a few cases where you can get away with that, but it's very much implementation specific.

Swig C++ Lua Pass class by reference

I don't know why I'm having a hard time with this. All I want to do is this:
class foo {
public:
foo(){}
~foo(){}
float a,b;
};
class foo2 {
public:
foo2(){}
foo2(const foo &f){*this = f;}
~foo2(){}
void operator=(const foo& f){
x = f.a;
y = f.b;
}
float x,y;
};
/* Usage(cpp):
foo f;
foo2 f2(f);
//or using the = operator
f2 = f;
*/
The problem I'm having is that, after swigging this code, I can't figure out how to make the lua script play nice.
/* Usage(lua)
f = example.foo()
f2 = example.foo2(f) --error
*/
The error I get is "Wrong arguments for overloaded function 'new_Foo2'":
Possible c/c++ prototypes are:
foo2()
foo2(foo const &)
The same thing happens if I try and use do f2 = f. As I understand it everything is stored as a pointer so I did try adding an additional constructor that took a pointer to foo but to no avail.
In the copy constructor you have the reference operator in the wrong place, put it after 'foo'. As your code stands it doesn't compile, at least not for me on VS 2008.
Edit: I see, thanks for the update. Well I'm not particularily familiar with LUA, but I know when porting from C++ to C# there are a few things that change when it comes to references. So my only idea would be if you need to explicitly show that you are passing a variable by ref/const ref. Ie. in C# to pass by ref in a function call you need:
int a = 10;
foo(ref a);
So something similar to this in LUA might cause the errors you show.
God only knows what SWIG is doing. My advice is to bite the bullet and use Lua's C API, which also works with C++. It's not that hard to learn, and you'll be able to overload the foo2 method exactly the way you want. Good examples can be found in Roberto Ierusalimschy's book Programming in Lua; you can get the previous edition free online.
N.B. Since the API is C, it doesn't know from reference parameters. Your Lua userdata object should contain a pointer to the C++ object of class foo2.
Along the lines of the suggestion to use Lua's native C API, but since you're in C++, try out Luabind. It works very well once you get the hang of it. If you do try it be sure to get the latest version--it's actively maintained and getting better all the time.
If you make the lua interface with swig try this instead:
foo2(const foo* f){*this = *f;}
swig has some problems with the reference types but make the automatic conversion from pointers without problems.
I think that the const reference is the problem in swig here
You can tell SWIG how to convert the internal pointer representation to a const reference using a typemap:
%typemap(in) const Foo&
{
if(!SWIG_IsOK(SWIG_ConvertPtr(L,$argnum, (void**)$1, $1_descriptor,1)))
{
SWIG_fail;
}
}
This should generate code that looks something like this in your wrap.cpp file:
if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_Foo,1)))
{
SWIG_fail;
}
result = new Foo2(((Foo const &)*arg1);
SWIG_arg=0;
SWIG_Lua_NewPointerObj(L, result, SWIGTYPE_p_Foo2, 1); SWIG_arg++;