Compile error when I #include "gmock/gmock.h" - c++

I'm attempting to integrate googlemock into my tests. I had already successfully built and run tests on googletest, and now am trying to incrementally add the gmock functionality into the tests as well, but I've hit a compile error that I utterly do not understand.
I am not attempting to use or define mocked classes, or use anything gmock.h provides. At the top of my (previously working) tests.cpp file I merely type
#include "gmock/gmock.h"
And I get the compile error:
gmock/gmock-matchers.h(2497) : error C2059: syntax error : 'sizeof'
gmock/gmock-matchers.h(2505) : see reference to class template
instantiation 'testing::internal::ElementsAreMatcherImpl'
being compiled
gmock/gmock-matchers.h(2497) : error C2059: syntax error : ')'
gmock/gmock-matchers.h(2497) : error C2143: syntax error : missing ')'
before '{'
gmock/gmock-matchers.h(2497) : error C4430: missing type specifier -
int assumed. Note: C++ does not support default-int
gmock/gmock-matchers.h(2499) : warning C4183: 'Message': missing
return type; assumed to be a member function returning 'int'
I'm compiling this using nmake/vc++ on Windows 7, and I can't fathom why I would get these compile errors simply from adding the core gmock include file to my test file. Has anyone seen this sort of thing before?

Did you init google mock with InitGoogleMock(&__argc, __argv) in test project's main function?
You should include only "gmock/gmock.h" in your test files (and where you call InitGoogleMock) - no need for inclusion of gtest.h.
Have you updated your googletest library to googlemock. (https://github.com/google/googletest)
If all the things above are true it should work.

#include <iostream>
#include "gmock/gmock.h"
template <typename T>
class Foo : private T {
public:
void foo() {
T::bar();
}
};
class Bar {
public:
void bar() {
std::cout << "Hey there!" << std::endl;
}
};
int main() {
Foo<Bar> f;
f.foo();
}
template <typename T>
class Foo : private T {
public:
void foo() {
T::bar();
}
};
class Bar {
public:
void bar() {
std::cout << "Hey there!" << std::endl;
}
};
int main() {
Foo<Bar> f;
f.foo();
}

Related

Templated class-- semicolon after constructor?

I have a templated class:
template <typename vtype>
class BNode
{
public:
BNode::BNode(std::vector<BPoly<vtype>>& thePolys) {if(thePolys.size()) Build(thePolys);}
BNode::BNode() {}
BPlane* mPlane=nullptr;
//And more stuff
};
When I compile, I get this error on the BPlane* mPlane=nullptr line:
error C2146: syntax error: missing ';' before identifier 'BPlane'
(Using Visual Studio 2019 compiler)
Why do I need a semicolon after my {}? If I put the semicolon there, it works. But I'm curious what the problem is because I'm worried there's some issue that will bite me later.
The following code compile without any error:
#include <vector>
class BPlane;
template <class T> class BPoly { int i; };
template <typename vtype>
class BNode
{
public:
BNode(std::vector<BPoly<vtype>> &thePolys) { if (thePolys.size()) Build(thePolys); }
BNode() {}
BPlane *mPlane = nullptr;
void Build(...) {}
//And more stuff
};
int main()
{
BNode<char> s;
}
Thus, it is impossible to guess what you have done wrong as after writing simple types for missing declaration and including vector the code compile without adding any ; after a constructor.
And I have made an instantiation in main to be sure that the class is used.

Code Compilation Fails on Linux, Succeeds on Windows: Cause/Fix?

I have some c++ code that will compile fine in Visual Studio 2013 but will not compile in linux using g++ (no IDE).
What is causing the difference and how can I make the code compile on linux? Is it because they are different compilers? Do I need a specific compiler setting?
Code:
#include <iostream>
typedef class IApp;
typedef class Component;
class Component
{
public:
protected:
IApp* app;
template<typename T>
void registerEvent()
{
app->logEvent();
}
};
class IApp : protected Component
{
public:
static IApp NULL_APP;
void logEvent()
{
printf("Event Logged\n");
}
protected:
virtual void foo() = 0;
};
int main(int argc, char** argv)
{
printf("Alive\n");
system("pause");
return 0;
}
On windows I get no compiler errors. On linux I get the following compiler errors:
g++ - o res main.cpp - std = c++11
main.cpp:3 : 15 : warning : ‘typedef’ was ignored in this declaration[enabled by default]
typedef class IApp;
^
main.cpp:4 : 15 : warning : ‘typedef’ was ignored in this declaration[enabled by default]
typedef class Component;
^
main.cpp: In member function ‘void Component::registerEvent()’ :
main.cpp : 16 : 6 : error : invalid use of incomplete type ‘class IApp’
app->logEvent();
^
main.cpp:3 : 15 : error : forward declaration of ‘class IApp’
typedef class IApp;
^
main.cpp: At global scope :
main.cpp : 23 : 14 : error : cannot declare variable ‘IApp::NULL_APP’ to be of abstract type ‘IApp’
static IApp NULL_APP;
^
main.cpp:20 : 7 : note : because the following virtual functions are pure within ‘IApp’ :
class IApp : protected Component
^
main.cpp : 31 : 15 : note : virtual void IApp::foo()
virtual void foo() = 0;
^
make: ***[all] Error 1
Here you should simply remove typedef:
typedef class IApp;
Then this template method should be defined out-of-line, below IApp:
template<typename T>
void registerEvent()
{
app->logEvent();
}
Otherwise, it doesn't see the declaration of IApp which it needs to dereference.
Finally, this does not make sense:
virtual void foo() = 0;
Because the same class has a static member of its own class type, so needs to instantiate it. But you've prevented that with a pure virtual function.
GCC is right not to compile this code.
Leave out the typedef keywords before the forward class declarations, they're not necessary. Just class MyClass; is sufficient for a forward declaration. The other issue is that foo() is pure virtual - you need to implement it if you want to instantiate the class. I'm surprised the Microsoft complier doesn't complain but then that's Microsoft.

Forward declaration inside a namespace

I've encountered a strange problem when trying to compile my code in Visual Studio (2010); here's an isolated (and simplified) example:
class A
{
public:
enum {
VALUE = 0
};
};
namespace ns
{
class A;
class B
{
public:
B(int val = ::A::VALUE) // this line
{}
};
class A : public ::A
{
public:
};
}
This gives the following error: error C2027: use of undefined type 'ns::A'. Is it a bug in VS or am I doing something wrong?
Update: this appears to be a bug specific to Visual Studio. Here's a workaround suggested on Microsoft Connect:
class B
{
public:
typedef ::A A1;
B(int val = A1::VALUE)
{}
};
This is a bug in VC10. Your ::A class name is fully qualified, and the definition of A in the global namespace is visible to the compiler. Besides, GCC 4.7.2 compiles this without problems.

Error when friending a function

I'm trying to work around the limitation that the default ctor of a custom Qt meta type has to be public by declaring certain functions as friends.
#include <QMetaType>
class QVariant;
template<typename T> inline T qvariant_cast(const QVariant &); // from qvariant.h
namespace foo
{
class Bar
{
private:
Bar(){};
friend void *::qMetaTypeConstructHelper<Bar>(const Bar *t); // works
friend inline Bar ::qvariant_cast<Bar>(const ::QVariant &v); // error C4430: missing type specifier
};
} // namespace foo
Q_DECLARE_METATYPE(foo::Bar)
void main()
{
QVariant v;
v.value<foo::Bar>();
}
When commenting out the marked line, I get the following error, which is expected:
1>[...]\qvariant.h(577): error C2248: 'foo::Bar::Bar' : cannot access private member declared in class 'foo::Bar'
But declaring the function as a friend doesn't work:
Bar.cpp(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
It almost seems like MSVC 2010 doesn't see the space between the "Bar" and the "::".
Aside from making the default ctor public, how can I get it to compile?
It almost seems like MSVC 2010 doesn't see the space between the "Bar" and the "::".
Spaces don't matter around :: meaning foo::bar is the same as foo ::bar.
Try adding parenthesis around the function name:
friend inline Bar (::qvariant_cast<Bar>)(const ::QVariant &v);

Why i am getting error while executing with the following code?

Technique 1 -> Results in error
I have three files MyType.h, MyType.cpp & main.cpp
MyType.h
#ifndef MYTYPE_H
#define MYTYPE_H
#include<iostream>
using namespace std;
template <class T,int iMax>
class A{
T iData;
public:
void vSetData(T iPar1);
void vDisplayData();
};
#endif
MyType.cpp
#include"MyType.h"
void A::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
void A::vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
main.cpp
#include"MyType.h"
typedef A<int,20> MyType;
int main(){
int x = 12;
MyType obj;
obj.vSetData(12);
obj.vDisplayData();
return 0;
}
ERRORS: 10 errors. They are as follows:-
mytype.cpp(2) : error C2955: 'A' : use of class template requires template argument list
mytype.h(9) : see declaration of 'A'
mytype.cpp(2) : error C2955: 'A' : use of class template requires template argument list
mytype.h(9) : see declaration of 'A'
mytype.cpp(2) : error C2065: 'T' : undeclared identifier
mytype.cpp(2) : error C2146: syntax error : missing ')' before identifier 'iPar1'
mytype.cpp(2) : error C2761: 'void A::vSetData(T)' : member function redeclaration not allowed
mytype.cpp(2) : error C2059: syntax error : ')'
mytype.cpp(2) : error C2143: syntax error : missing ';' before '{'
mytype.cpp(2) : error C2447: '{' : missing function header (old-style formal list?)
mytype.cpp(6) : error C2955: 'A' : use of class template requires template argument list
mytype.h(9) : see declaration of 'A'
mytype.cpp(6) : error C2509: 'vDisplayData' : member function not declared in 'A'
mytype.h(9) : see declaration of 'A
Technique 2 -> Works fine.
AboveCodeInOneFile.cpp
#include<iostream>
using namespace std;
template <class T,int iMax>
class A{
T iData;
public:
void vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
void vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
};
typedef A<int,20> MyType;
int main(){
int x = 12;
MyType obj;
obj.vSetData(12);
obj.vDisplayData();
return 0;
}
Please let me know what mistake i am doing in Technique 1
When defining a template class, the method definition must be seen by the compiler. So they have to be in the header file.
Edit
You have to include the method implementation, so it's seen by the compiler. You can do it by including them from another `MyType_impl.h" file:
template <class T, int iMax>
void A<T, iMax>::vDisplayData()
{
cout<<"\nData is: "<<iData<<endl;
}
Each method definition needs the full class name decoration above it:
template <typename T>
void A<T>::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
template <typename T>
void A<T>::vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
When you do this however you'll get other compile errors, for the reasons Abhineet outlined. To fix this, you could put the definitions I wrote into the header file, beneath the class declaration, or you could put it in another header (MyType_Inc.h) and include /that/ header in the class declaration header
Technique 1 is wrong for templates. Don't use it.
Think of templates as blueprints for actual functions. Blueprints by themselves are not compilable. Only when you substitute template arguments (<class T,int iMax>) the actual functions are built. Because of this the compiler must see the blueprints when it tries to build functions from templates. In order to see the blueprints they must reside completely in header files.
When you define the member functions, you have to repeat the template parameters
template <class T,int iMax>
void A<T, iMax>::vSetData(T iPar1)
{
if(iPar1 <= iMax)
iData = iPar1;
}
That saves you from the compile errors.
The next problem is that templates defined in a .cpp file can only be used in that file. If you want to use them somewhere else, you really should put the definitions in the header.
There are two problems with your first version.
When implementing a member of a class template outside the class, you need to declare it as a template:
template <class T,int iMax>
void A<T,iMax>::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
Also, the function definitions need to be available in any compilation unit that instantiates the template. In practice, this means you should usually define them inline (either inside the class template definition, or outside it but in a header file and declared inline). Simply defining them in a source file like you do will cause link errors.