I'm create my own LOGGER, where I use an additional class for overload macro.
There is #define qlcd MacroCall(QLC::Debug), so i can use logger like this: qlcd << message;
It's ok, but when i try use qlcd("log name") i got an error. Look minimal code (no macro for simplify):
#include <QVariant>
#include <QDebug>
class QLC
{
public:
// Error types
enum LevelType{
Debug=0, // Debug
Error=1, // Error
WTF = 2 // WTF???
} level;
QString logger;
// Constructors
QLC(QLC::LevelType l)
:level(l), logger(":")
{}
QLC(QLC::LevelType l, QString log)
:level(l), logger(log)
{}
// OPERATOR <<
QLC& operator<<(const QVariant var){
qDebug() << "(" + QString::number(level) + ")" << logger << var;
}
};
class MacroCall
{
QLC::LevelType level;
public:
MacroCall()
:level(QLC::Debug){}
MacroCall(int i)
:level(QLC::WTF){}
MacroCall(QLC::LevelType l)
:level(l){}
QLC operator()(){
return QLC(level);
}
QLC operator()(QString log){
return QLC(level, log);
}
};
int main(int argc, char*argv[])
{
MacroCall()("WorkLog") << "No level, yes logname";
MacroCall(QLC::Error)() << "No logname, yes level";
MacroCall a(QLC::Error);
a("WorkLog") << "Logname and level at different lines";
// GET READY!
// INT as level and logname:
MacroCall(2)("WorkLog") << "WTF?? It works!";
//MacroCall(QLC::WTF)("NotWorkLog") << "It's not work!!!!!!";
// NOT WORK: error: invalid use of qualified-name 'QLC::WTF'
// Qt 4.8.3
return 0;
}
The code
MacroCall(QLC::WTF)("NotWorkLog")
is interpreted as declaration of a variable:
MacroCall QLC::WTF("NotWorkLog")
Example:
class A
{
public:
enum E {
x=1
};
public:
A(E) {}
void operator()(int) const { }
};
class B {};
void f()
{
(A(A::x))(1); // Ok
A{A::x}(1); // Ok
A(a)(A::x); // Ok
A::E a; // ‘a’ has a previous declaration as ‘A a’
A(A::x)(1); // invalid use of qualified-name ‘A::x’
B(b)(A::x); // no matching function for call to ‘B::B(A::E)’
}
The code you gave compiles (except that the method QLC& operator<<(const QVariant var) has to return something), eventhough I'm not sure of how it's supposed to be used.
My guess is that your 2 classes are defined in different headers and an include is missing. Does Macrocall header include QLC header ?
Related
I have the following problem, I have a class that I want to be constructed from two different kinds of complex objects. There is a map inside a class method, that constructs from extern variables that I defined in the outer of the class. If I want to declare a class object inside the main function everything goes fine. But if I declare it outside the main, constructor of the class is called before the initialization of the extern objects from which I constructed the inner map in the class method. The error repeats itself on Clang and MSVC. If I use simple objects to construct the map (like int or double), everything works fine in both ways.
main.cpp
#include "TestClass.h"
TestClass test1 = TestClass(g_Spec1); // 1
int main()
{
TestClass test2 = TestClass(g_Spec1); // 2
}
If you comment 1 everything works fine, however, as is, 2 didn't see extern variables.
TestClass.h
#pragma once
#include <iostream>
#include <map>
#include "Token.h"
extern const Spec_t g_Spec1;
extern const Spec_t g_Spec2;
extern const Spec_t g_Spec3;
extern const Name_t g_Name1;
extern const Name_t g_Name2;
extern const Name_t g_Name3;
class TestClass {
private:
Name_t name;
Spec_t spec;
static const Name_t& foo(const Spec_t& j);
public:
TestClass() = default;
TestClass(const Spec_t& j);
virtual ~TestClass() = default;
};
TestClass.cpp
#include "TestClass.h"
const Spec_t g_Spec1{ {Token::Type1, 2} };
const Spec_t g_Spec2{ {Token::Type1, 3} };
const Spec_t g_Spec3{ {Token::Type1, 4} };
const Name_t g_Name1{ "Name1" };
const Name_t g_Name2{ "Name2"};
const Name_t g_Name3{ "Name3" };
const Name_t& TestClass::foo(const Spec_t& spec_)
{
static const std::map<Spec_t, Name_t > glmap1 =
{
{g_Spec1, g_Name1},
{g_Spec2, g_Name2}
};
std::cout << "Foo: Map size must be 2, but it is " << glmap1.size() << std::endl;
std::cout << "In FOO Name1 is " << g_Name1 << std::endl;
auto constIterator = glmap1.find(spec_);
if (constIterator == glmap1.cend())
{
std::cout << "Not found " << std::endl; // 3
return g_Name3;
}
else
{
std::cout << "Found " << constIterator->second << std::endl; // 4
return constIterator->second;
}
}
TestClass::TestClass(const Spec_t& j)
{
name = foo(j);
spec = j;
std::cout << "In CONSTRUCTOR name as global variable from map " << name << std::endl;
}
Another interesting thing is that 1 call 4(Found) and 2 calls 3(Not found) but the map is empty in both ways. Maybe it is because g_Spec1 didn't initialize at this time?
And I didn't get why the map inside is debugger is empty, but have size = 1
Token.h
#pragma once
#include <cinttypes>
#include <string>
#include <vector>
enum class Token
{
Type1,
Type2
};
struct TokenId
{
Token tok;
std::uint64_t val;
bool operator==(const TokenId& p_Other) const noexcept
{
return (tok == p_Other.tok && val == p_Other.val);
}
bool operator<(const TokenId& p_Other) const noexcept
{
if (tok < p_Other.tok) return true;
else if (tok == p_Other.tok)
{
return val < p_Other.val;
}
else return false;
}
};
using Name_t = std::string;
using Spec_t = std::vector<TokenId>;
This is not entirely surprising. Initialization of global objects is partially ordered. Definitions from a single file are ordered by their appearance within that file, but there is no order across files.
You might see unexpected results in a debugger, because using uninitialized variables is undefined behavior.
This is just one of the reasons why global variables are best avoided. In your case, just put that variable inside main().
I'm working on a simple program for Boolean algebra, but the double negation does not work as expected.
I have the following classes:
Operator:
#ifndef OPERATOR_H
#define OPERATOR_H
class Operator {
public:
virtual int getArity(void) const = 0;
virtual bool calc(void) const = 0;
};
#endif // OPERATOR_H
False:
#ifndef FALSE_H
#define FALSE_H
#include "operator.h"
class False : public Operator {
public:
int getArity() const {
return 0;
}
bool calc(void) const {
return false;
}
};
#endif // FALSE_H
Not:
#ifndef NOT_H
#define NOT_H
#include "operator.h"
class Not : public Operator {
public:
Not(Operator& child) : m_child(child) {
std::cout << "not constructor called" << std::endl;
}
int getArity(void) const {
return 1;
}
bool calc(void) const {
return !m_child.calc();
}
private:
Operator& m_child;
};
#endif // NOT_H
My main.cpp:
#include <iostream>
#include "operator.h"
#include "not.h"
#include "false.h"
using namespace std;
int main(int argc, char *argv[]) {
False f;
Not n = Not(f);
Not d = Not(n);
cout << "n.calc(): " << n.calc() <<endl;
cout << "d.calc(): " << d.calc() <<endl;
return 0;
}
Since d = Not(Not(False())) I expect it to be false.
The output is:
not constructor called
n.calc(): 1
d.calc(): 1 <== should be 0
Why is the constructor of the class Not not called with an object of type Not as child?
Not d = Not(n); invokes the copy constructor of Not, because the argument is also of type Not. The copy constructor's signature matches better and it's therefore selected.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have base class State and derived class InitialState.When i build solution compiler show error C2509: 'setView': member function not declared in 'InitialState' and I don't know why...
Here is State.h :
#ifndef STATE_H
#define STATE_H
#include<iostream>
using namespace std;
class State {
public:
State() { isPrototype = true; }
virtual void execute() = 0;
virtual void setView(ostream& screen) const = 0;
virtual void onEnter() { system("CLS"); setView(cout); }
virtual void onExit() = 0;
private:
bool isPrototype;
State* nextState;
};
#endif
InitialState.h :
#ifndef INITIAL_STATE_H
#define INITIAL_STATE_H
#include"State.h"
class InitialState : public State {
public:
void execute() {}
void onExit() {}
void setView(ostream& screen) const;
};
#endif
and InitialState.cpp:
#include"InitialState.h"
void InitialState::setView(ostream& screen) const {
screen << "Welcome!" << endl;
screen << "Please select what you want to do: " << endl << "1.Load card" << endl << "0.Exit" << endl;
}
I have tried to add key word "virtual" in the front of functions in InitialState.h , but it doesn't change anything...also when I delete InitialState.cpp the code compiles normaly.
Here is the AtmTest.cpp:
#include "PaymentCard.h"
//#include "Atm.h"
int main() {
return 0;
}
but it has nothing with State...
and here are the other classes:
Atm.h:
#ifndef ATM_H
#define ATM_H
#include<iostream>
using namespace std;
class Atm {
public:
static Atm* get();
static void release() { delete instance; instance = nullptr; } //Singleton
private:
int serialNumber;
string bankName;
string location;
//Singleton:
Atm();
static Atm* instance;
Atm(const Atm& m) = delete;
Atm& operator=(const Atm& m) = delete;
Atm(Atm&&) = delete;
Atm& operator=(Atm&& m) = delete;
};
#endif
Atm.cpp:
#include"Atm.h"
//Singleton:
Atm* Atm::instance = nullptr;
Atm* Atm::get() {
if (instance == nullptr) {
instance = new Atm();
}
return instance;
}
PaymentCard.h:
#ifndef PAYMENT_CARD_H
#define PAYMENT_CARD_H
#include<iostream>
using namespace std;
class PaymentCard {
public:
PaymentCard(string clientName);
void addMoney(unsigned int amount) { currentAmount += amount; }
void withdrawMoney(int amount);
friend ostream& operator<< (ostream&, const PaymentCard&);
private:
static int NumberGenerator;
unsigned int serialNumber;
string clientName;
int currentAmount;
};
#endif
PaymentCard.cpp:
#include"PaymentCard.h"
int PaymentCard::NumberGenerator = 0;
PaymentCard::PaymentCard(string clientName) {
currentAmount = 0;
this->clientName = clientName;
serialNumber = NumberGenerator++;
}
void PaymentCard::withdrawMoney(int amount) {
if (amount > currentAmount)cout << "Ovde ide izuzetak";
else currentAmount -= amount;
}
ostream& operator<< (ostream &os, const PaymentCard& card){
os << card.serialNumber + 1 << ". Client: " << card.clientName << endl;
return os;
}
This code is not near the finish, but it worked until i have made SetView in InitialState, so idk what happened..
The problem: InitialState.h is precompiled, and you are linking to a prior version of InitialState.h. Clean, rebuild, and/or disable precompiled headers altogether.
I suspect that, because:
I can reproduce the error by commenting out the declaration of setView() in InitialState.h
The resulting error message refers to line 3 of InitialState.cpp and the error message you posted refers to line 6, which indicates that the posted source code did not produce that error message.
To reproduce the error, one has to comment out the setView() decalration from the InitialState class:
class InitialState : public State {
public:
void execute() {}
void onExit() {}
//void setView(ostream& screen) const;
};
Then one gets the following error message:
1>InitialState.cpp(3): error C2509: 'setView' : member function not declared in 'InitialState'
1> c:\users\laci\desktop\samples\stackoverflow\InitialState.h(6) : see declaration of 'InitialState'
I am investigating Gmock (Google Test Framework).
I run into an issue which I think Gmock can resolve it but It cannot. Please have a look to:
#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace std;
using ::testing::Invoke;
//---- THINGS TO TEST ---------
class MyTest {
public:
void display(const char* str);
void show_text();
};
void MyTest::display(const char* str){
cout << __func__<< " " << str << "\n";
cout << ":-->Inside the display myTest\n";
}
void MyTest::show_text(){
display("INSIDE MYTEST"); // HOW to mock display() here ?
}
//-------------------------------
//--- Configuration to test myTest ----
template <class myclass>
class Caller {
public:
myclass T;
void call_show_text() ;
void call_display(const char* s) ;
};
template <class myclass>
void Caller<myclass>::call_show_text()
{
T.show_text();
}
template <class myclass>
void Caller<myclass>::call_display(const char* str)
{
T.display(str);
}
void my_display(const char* str){
cout << __func__<< " OUTSIDE MYTEST\n" <<":-->Outside the display myTest\n";
}
struct MockTest {
MOCK_METHOD1(display, void(const char*));
MOCK_METHOD0(show_text, void());
};
//-------------------------------
//----- Test cases -------------
//----- Test cases -------------
TEST(TestShowTextMethod, CallDisplayOfmyTest){
Caller<MyTest> obj1;
obj1.call_show_text();
}
TEST(TestShowTextMethod, ReroutingDisplayToNewFunctionWithCallDisplay){
Caller<MockTest> obj2;
EXPECT_CALL(obj2.T, display("test_obj_2"))
.Times(1)
.WillOnce(Invoke(my_display));
obj2.call_display("test_obj_2");
}
TEST(TestShowTextMethod, ReroutingDisplayToNewFunctionWithCallShowText){
Caller<MockTest> obj3;
EXPECT_CALL(obj3.T, display("test_obj_3"))
.Times(1)
.WillOnce(Invoke(my_display));
obj3.call_display("test_obj_3");
}
TEST(TestShowTextMethod, ReroutingToNewFunctionWithCallShowText){
const char * str = "INSIDE MYTEST";
Caller<MockTest> obj4;
EXPECT_CALL(obj4.T, show_text());
EXPECT_CALL(obj4.T, display(str))
.Times(1)
.WillOnce(Invoke(my_display));
obj4.call_show_text();
}
//-------------------------------
//--- Initialization for test ----
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Only focus on the 4th test, I think Gmock can handle the fourth TEST: show_text calls display, why I can't mock display in this case ? Is Gmock impossible to mock a method is called in another method in the same class or I made a certain mistake in the 4th testcase ? I got a failed test-result like this:
../test_program.cpp:100: Failure
Actual function call count doesn't match EXPECT_CALL(obj4.T, display(str))...
Expected: to be called once
Actual: never called - unsatisfied and active
Of course, show_text and display() are exactly called.
Does anybody have an idea ?
why I can't mock display in this case?
You have not only successfully mocked display but also show_text as well. You should not lean on the behaviour of mocked implementation, because it will not be called.
Is Gmock impossible to mock a method is called in another method in the same class.
It is possible, but far from pretty, You can find example below. Note that there are some trade-offs made only for tests. Making DisplayController::display a virtual class is probably the biggest one.
class DisplayController
{
public:
virtual void display(const std::string& text)
{
cout << text << endl;
}
void show_str(const std::string& text)
{
cout << "Start" << endl;
display(text);
cout << "End" << endl;
}
};
class TestableDisplayController : public DisplayController
{
public:
MOCK_METHOD1(display, void(const std::string&));
MOCK_METHOD1(show_str_called, void(const std::string&));
void show_str(const std::string& text)
{
show_str_called(text);
DisplayController::show_str(text);
}
};
template <typename T>
class ClassUnderTest
{
public:
ClassUnderTest(T& display)
: displayController(display)
{}
void callDirectDisplay(const std::string& text)
{
displayController.display(text);
}
void callIndirectDisplay(const std::string& text)
{
displayController.show_str(text);
}
private:
T& displayController;
};
TEST(test, example)
{
TestableDisplayController mockedDisplayController;
ClassUnderTest<TestableDisplayController> sut(mockedDisplayController);
std::string l_directDisplay = "directDisplay";
std::string l_indirectDisplay = "indirectDisplay";
EXPECT_CALL(mockedDisplayController, display(l_directDisplay));
sut.callDirectDisplay(l_directDisplay);
EXPECT_CALL(mockedDisplayController, display(l_indirectDisplay));
EXPECT_CALL(mockedDisplayController, show_str_called(l_indirectDisplay));
sut.callIndirectDisplay(l_indirectDisplay);
}
when compile, it occurs an error:
PagingInfo.hpp:35: error: ‘StringBuilder’ was not declared in this scope.
I have inlude the right head file, but why compiler can not find the difinition of StringBuilder?
Utils.hpp:
#ifndef LIBFACEBOOKCPP_UTILS_H_
#define LIBFACEBOOKCPP_UTILS_H_
template<class TData, class TStr>
inline TData fromString(const TStr &str)
{
std::stringstream oss;
oss << str;
TData t;
oss >> t;
return t;
}
class StringBuilder
{
public:
inline operator const std::string () const
{
return oss.str();
}
private:
std::ostringstream oss;
};
#endif // LIBFACEBOOKCPP_UTILS_H_
PagingInfo.hpp
#ifndef LIBFACEBOOKCPP_PAGING_INFO_H_
#define LIBFACEBOOKCPP_PAGING_INFO_H_
#include "Utils.hpp"
namespace LibFacebookCpp
{
struct PagingInfo
{
PagingInfo(unsigned int offset_, unsigned int limit_) : offset(offset_), limit(limit_) { }
bool IsValid() const { return 0 != limit; }
void GetUri(Uri *uri) const
{
LIBFACEBOOKCPP_ASSERT(uri);
uri->query_params["limit"] = StringBuilder() << offset;
uri->query_params["offset"] = StringBuilder() << limit;
}
...
};
} // namespace LibFacebookCpp
#endif // LIBFACEBOOKCPP_PAGING_INFO_H_
When I add enough skeleton code to get this down to just your issue in ideone, I get a different error:
prog.cpp: error: no match for 'operator<<' in 'StringBuilder() << ((const LibFacebookCpp::PagingInfo*)this)->LibFacebookCpp::PagingInfo::offset'
Your StringBuilder class does not have a << operator defined. In order to use:
StringBuilder() << offset;
You will need to define one.
Between you and me, there are about 15 overloads of that operator for stringstreams (one for every primitive type). It would be a massive waste of time to reimplement all of them. Just use a stringstream.