Visual Studio 2010 compile error with std::string? - c++

So this is possibly the strangest thing I've seen recently and was curious how this could happen. The compiler gave me an error saying that std::string is undefined when used as a return type but not when used as a parameter in methods of a class!
#pragma once
#include <string>
#include <vector>
// forward declarations
class CLocalReference;
class CResultSetHandle;
class MyClass
{
public:
MyClass() {}
~MyClass {}
void Retrieve(const CLocalReference& id, CResultSetHandle& rsh, std::string& item); // this is fine
const std::string Retrieve(const CLocalReference& id, CResultSetHandle& rsh); // this fails with std::string is undefined?!?!
};
Doing a Rebuild All it still happened I had to choose clean solution and then Rebuild All again after for the universe to realign. While it's resolved for the moment I'd still like to know what could have caused this because I'm at a loss as to why when there should be no conflicts especially when I always use fully qualified names for STL.

This is probably a compiler bug. I have seen several others in VS2010.

Related

TBB compiler error - 'my_task': references must be initialized

I use TBB at multiple places in my project. But it seems that since I update Visual Studio from 15.6.X (X beeing the latest version) to 15.7.1 I get a compiler error at several places, telling me
[...]tbb\task_group.h(94): error C2530: 'my_task': references must be initialized
Looking at the referenced code (tbb/task_group.h):
//! Base class for types that should not be assigned.
class no_assign {
// Deny assignment
void operator=( const no_assign& );
public:
#if __GNUC__
//! Explicitly define default construction, because otherwise gcc issues gratuitous warning.
no_assign() {}
#endif /* __GNUC__ */
};
//! Base class for types that should not be copied or assigned.
class no_copy: no_assign {
//! Deny copy construction
no_copy( const no_copy& );
public:
//! Allow default construction
no_copy() {}
};
// ...
class ref_count_guard : internal::no_copy {
task& my_task; // compiler error occurs here
public:
ref_count_guard( task& t ) : my_task(t) {
my_task.increment_ref_count();
}
~ref_count_guard() {
my_task.decrement_ref_count();
}
};
I don't see why the compiler is complaining there, as the reference is initialized by the constructor. Finding the problem in my code is also not that easy, because the compiler error occurs in every single source file that uses TBB and I don't think I changed anything since my last successful compilation (besides updating VS).
One possibility that comes to my mind is related to this question. If msvc somehow inherits the base class constructors by default, a default constructor would be inherited explaining the error. But testing this scenario seems to disprove it (as the code compiles).
Why is msvc complaining here?
Update
This minimal example reproduces the error on my system:
#include <vector>
#include <tbb/tbb.h>
#include <tbb/flow_graph.h>
void main()
{
std::vector<int> src{1, 2, 3, 4, 5};
tbb::parallel_for_each(src.begin(), src.end(), [](int) { });
}
Update 2
Looks like just including tbb/tbb.h causes the error to occur. I don't even need to call anything. Rebuilding tbb with the new compiler version didn't help either.
Edit
Cross issue on github.
Simply removing /permissive- (e.g. set Comformance Mode to No in the C/C++ options) gets past this issue. I presume Intel will fix this soon.
This is a compiler bug when /permissive- option is used. It can be reproduced with the following code:
struct U {
template<typename T>
void foo() {
class A {
int& iref;
public:
A(int& ir) : iref(ir) { }
};
int the_answer = 42;
A a(the_answer);
}
};
int main() {
U u;
u.foo<int>();
return 0;
}
The code is perfectly valid, compliant C++. As you can see, the reference is explicitly initialized in the member initializer list of the constructor. Also this is seemingly a regression in VS, because at least the initial release of VS 2017 (15.0.something) compiles this code with /permissive-.

The text "<" is unexpected when compiling with Xlc_r IBM compiler

I have a problem with the compiling of code with the xlC_r compiler on AIX OS. I have attached my code below which is causing the problem. I have tried to compile the
code on MS Windows with microsoft compiler and also compiled it under Linux with gcc and everything worked fine. The compiler error which I get is following:
"...../ABC.h", line 12.22: 1540-0063 (S) The text "<" is unexpected.
I have searched the internet and I found some resources (link and link), I do not know how to integrate the solution into my code. One possible solution
would be to remove the shared_ptr and just have the pointer value, but I do not like to manage the deleting of pointer by myself. I would relly appreciate any help.
ABC.h
#ifndef ABC_H
#define ABC_H
#include <vector>
#include <memory>
template<class SR_TYPE, class SM_TYPE>
class ABC {
private:
std::shared_ptr<SR_TYPE> mpRV;
std::vector<SM_TYPE> mMsgs;
public:
ABC(void);
ABC(SR_TYPE* pReturnValue);
virtual ~ABC(void);
}; // ABC
template<class SR_TYPE, class SM_TYPE>
ABC<SR_TYPE, SM_TYPE>::ABC(void) {
}
template<class SR_TYPE, class SM_TYPE>
ABC<SR_TYPE, SM_TYPE>::ABC(SR_TYPE* pReturnValue) {
mpRV.reset(pReturnValue);
}
template<class SR_TYPE, class SM_TYPE>
ABC<SR_TYPE, SM_TYPE>::~ABC(void) {
}
#endif // ABC_H
ABC.cpp
#include "ABC.h"
class ABCExtended : public ABC<int, std::string> {
ABCExtended() :
ABC<int, std::string>()
{}
ABCExtended(int* pReturnValue) :
ABC<int, std::string>(pReturnValue)
{}
};
Thanks in advance.
xlC is not C++11 conformant. Shared_ptr is not available there in std:: namespace. It does have special namespace for 'experimental' features, and shared_ptr might be there. Those expereimentals are in std::tr1, and you need to compile with __ IBMCPP_TR1__.
shared_ptr is from the TR1 so it should be used from that namespace
change
std::shared_ptr mpRV;
to
std::tr1::shared_ptr mpRV;
Compile with
-D__IBMCPP_TR1__

C++ - "Unspecialised class template" error with shared_ptr

I have a class Room and it holds a vector of shared_ptrs to Option objects like so:
private:
vector<shared_ptr<Option> > options;
But for some reason when I build, I get the following errors:
'shared_ptr' : unspecialized class template can't be used as a template argument for template parameter '_Ty', expected a real type
'std::tr1::shared_ptr' : use of class template requires template argument list
Strangely, I also have a vector of shared_ptrs, exact same syntax but there's no problem with that one.
There's also a bunch of places that bring up the error "'Option': undeclared identifier", which brings me to think it might be a problem with the Option class, but it seems to be fine. Here's the code for Option:
Option.h:
#pragma once
#include "Room.h"
#include <memory>
using namespace std;
class Option
{
protected:
int id;
char* text;
public:
Option(void);
Option(int, char*);
virtual ~Option(void);
char* getText();
int getID();
};
Option.cpp:
#include "Option.h"
#include "Room.h"
#include <memory>
using namespace std;
Option::Option(void)
{
}
Option::Option(int newID, char* newText){
id = newID;
text = newText;
}
Option::~Option(void)
{
}
char* Option::getText(){
return text;
}
int Option::getID(){
return id;
}
There is a bit of conjecture in this answer since you haven't posted the code for the Room class. I'm assuming this code
private:
vector<shared_ptr<Option> > options;
is in Room.h. Your Option.h file includes Room.h, hence the Room class gets declared before the Option class. So Option is an incomplete type when the Room class' destructor is compiled and the shared_ptr implementation tries to delete the Option object.
From the code above, I don't see why Option.h needs to include Room.h, in fact, it should be the other way around. If it does indeed need to include the file, you should be able to work around the problem by explicitly declaring Room::~Room() out-of-line in Room.cpp.
EDIT:
Turns out ~shared_ptr<T> does not require T to be a complete type. However, shared_ptr<T>( T* ) and shared_ptr<T>::reset( T* ) do, and the problem may be because some operation on the vector is invoking a call to one of these (more likely the former).
vector<shared_ptr<Option >>
You almost did that right :)
vector<shared_ptr<Option> >
It's the two > characters that, when touching, cause the strange errors you see. It is being interpreted as the >> operator.
BTW, thank you for posting your code exactly as it is rather than typing it back in and possibly hiding the mistake.

std::vector fails referencing the object to push in after code splitting

EDIT: aList was being referenced as a pointer in this version of my code, but not in my current version which still has the same problem.
I had this code perfectly working before trying to split it in an interface file and an implementation file. But when I splitted it, the compiler tells me I'm calling push_back() with incorrect parameters. So I understand it cannot reference the type of the object I'm pushing it, although it's the same (afaik, of course :D).
#ifndef _MYHEADER_HPP_
#define _MYHEADER_HPP_
class A{
public:
std::string someString;
};
class B{
public:
std::vector<A> aList;
public:
void addA();
};
#endif /* _MYHEADER_HPP_ */
//implementation file
#include <string>
#include <vector>
#include "myheader.hpp"
void B::addA(){
A a;
a.someString = "Hola";
// Here compiler says : Invalid arguments 'Candidates are: void push_back(const A &)' line 18 Semantic Error
aList.push_back(a);
}
AFAIK, std::vector always do a copy of the object to push, and that copy gets stored into the vector, so I think it's not a problem of 'a' being stack allocated, am I right?
What I'm doing wrong?
Thanks.
Ok, after more than 3 hours looking for the root of the problem, I found that Eclipse CDT IDE had a corrupted cache file about my code. So, compiling from command line was everything fine, I had to delete that cache file and then Eclipse reported no errors.

Error C2275 caused by template member function. Is this code wrong?

I think I've run into a (possible) VC6 (I know. It's what we use.) compiler error, but am open to the fact that I've just missed something dumb. Given the following code (It's just an example!):
#include <iostream>
// Class with template member function:
class SomeClass
{
public:
SomeClass() {};
template<class T>
T getItem()
{
return T();
};
};
// Dummy just used to recreate compiler error
class OtherClass
{
public:
OtherClass() {};
};
std::ostream& operator<<( std::ostream& oStr, const OtherClass& obj )
{
return oStr << "OtherClass!";
};
// Main illustrates the error:
int main(int argc, char* argv[])
{
SomeClass a;
OtherClass inst2 = a.getItem<OtherClass>(); // Error C2275 happens here!
std::cout << inst2 << std::endl;
return 0;
}
If I try to compile this code VC6, dies on a.getItem<OtherClass>() yielding:
Error C2275: 'OtherClass' : illegal use of this type as an expression.
Have I overlooked some trivial syntax issue? Am I breaking a rule?
This code compiles just fine under gcc 4.3.4. Is it yet another compliance issue with VC6?
Thanks!
Among many other things with the word template in it, VC6 couldn't deal with function templates where the template parameters aren't also function parameters. The common workaround was to add a dummy function parameter:
template<class T>
T getItem(T* /*dummy*/ = NULL)
{
return T();
} // note: no ; after function definitions
However, in general, VC6 is pretty lame and often chokes as soon as a TU contains the template keyword. I had to beat my head against it for several years (big code base compiled with several compilers/compiler versions; VC6 giving us an endless amount of trouble) and was very glad when I got rid of it in 2003.
This is likely to be a VC6 issue. Although VC6 compiles most basic templates correctly it is known to have many issues when you start to move towards the more advanced template uses. Member templates are an area where VC6 is known to be weak on conformance.
I believe that's another bug in VC6, you should really switch to a more up-to-date compiler.