I have this header file for a class Dictionary
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include <string>
#include <vector>
#include <unordered_set>
class Dictionary {
public:
Dictionary(string wordFile);
bool contains(const string& word) const;
vector<string> get_suggestions(const string& word) const;
private:
unordered_set<string> words;
};
#endif
and I'm getting the error "error: expected constructor, destructor, or type conversion before ‘(’ token Dictionary::Dictionary(string wordFile) ". In the .cpp file it looks like this:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <algorithm>
#include "word.h"
#include "dictionary.h"
#include <unordered_set>
#include <string>
Dictionary::Dictionary(string wordFile) {
string str;
ifstream input(wordFile);
while (getline(input, str)) {
words.insert(str);
}
}
bool Dictionary::contains(const string& word) const {
unordered_set<string>::const_iterator got = words.find(word);
if(got == words.end()){
return false;
}
return true;
}
vector<string> Dictionary::get_suggestions(const string& word) const {
vector<string> suggestions;
return suggestions;
}
I have no idea what's wrong... I come from a Java background and I'm having some trouble getting accustomed to writing in C++ and fixing these errors.
The original error was because you didn't qualify string in the header file:
Dictionary(string wordFile);
That should be:
Dictionary(std::string wordFile);
(and similarly for the other uses of string and unordered_map in the header).
You'll have the same problem in the .cpp file, but you can solve it there by simply adding using namespace std; to the top of the file, after all the #include directives. (You should not put using namespace in header files, or before including headers files, as it can have unwanted consequences and confuse later headers).
Related
I'm currently trying to playaround with operator overloading and built the following code
//Circle.cpp
//Circle.cpp
#ifndef CIRCLE_H
#define CIRCLE_H
#include "IOD.cpp"
#include<string>
class IOD; //Forward declaration
class Circle
{
public:
void display(IOD& ioDevice) const
{
ioDevice<<*this;
}
};
#endif
//IOD.cpp
//IOD.cpp
#ifndef IOD_H
#define IOD_H
#include <iostream>
#include<string>
#include "Circle.cpp"
class Circle; //Forward declaration
class IOD
{
// Interface for displaying CAD objects
public:
void operator<<(const Circle& c)
{
std::cout << "Displaying the object Circle Using IODevice GraphicsScreen for circles";
}
};
#endif
//Source.cpp
//Source.cpp
#include <iostream>
#include "Circle.cpp"
#include "IOD.cpp"
int main()
{
Circle* c1 = new Circle();
IOD* d1 = new IOD();
c1->display(*d1);
}
I'm trying to have the display function in Circle to call the overloaded operator << in IOD to print output about the Circle object to the screen. My understanding is that using "ioDevice<<*this" inside the display function should produce the desired output. But instead i'm getting the following error
error C2676: binary '<<': 'IOD' does not define this operator or a conversion to a type acceptable to the predefined operator
Any workarounds to this?
You have circular dependency between files: Circle.cpp includes IOD.cpp and vice versa.
In order to make it work fine you should split your cpp files into cpp and .h where .h will include only API definitions.
You should think of #include as "copy-paste".
I'm trying to develop a simple chat program using Boost. I came accross strange situation. I use netcat to listen at specific port while I run the program that's sending a simple text. Connection is established but the text is messed up. Actually instead of whole line I sometimes get one random characters or two. Im putting the code down below:
#include "lib/client.h"
#include <boost/asio.hpp>
#include <boost/asio/io_service.hpp>
#include <iostream>
#include <thread>
#include <string>
int main(int argc, char* argv[]){
if(argc != 3){
std::cout << "Wrong use. After specifying executable, add host and port\n";
return 0;
}
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
auto endpoint = resolver.resolve({argv[1],argv[2]});
Client c(io_service, endpoint);
std::thread t([&io_service](){ io_service.run();});
std::string text = "Welcome host!";
c.add_msg_to_deque(text);
t.join();
c.close();
return 0;
}
And here are client methods:
#include "../lib/client.h"
#include <boost/asio.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/array.hpp>
#include <deque>
#include <iostream>
#include <string>
void Client::connect(boost::asio::ip::tcp::resolver::iterator endpoint){
boost::asio::async_connect(socket, endpoint,
[this](boost::system::error_code ec, boost::asio::ip::tcp::resolver::iterator)
{
if (!ec)
{
}
});
}
void Client::close()
{
ios.post([this]() { socket.close(); });
}
void Client::add_msg_to_deque(const std::string& msg){
ios.post([this,msg](){
write_msg_deque.push_back(msg);
send_msg();
});
}
void Client::send_msg(){
boost::array<char,128> buf;
std::string temp_string = write_msg_deque.front();
std::copy(temp_string.begin(),temp_string.end(),buf.begin());
boost::asio::async_write(socket, boost::asio::buffer(buf,temp_string.size()),[this](boost::system::error_code ec, std::size_t){
if(!ec){
write_msg_deque.pop_front();
if(!write_msg_deque.empty())
send_msg();
}
else{
socket.close();
}
});
}
You are using async_write with local data it is bad idea. async_write returns immediately. After calling async_write your method send_msg terminates, so local data (buf array) is destroyed before your message is sent. You can use a synchronous version of IO functions to send data or keep buf as member of your class to provide data exists until data is sent successfully.
I have this code that attempts perfect forwarding of template parameters pack into std::function via intermediate class:
#include <functional>
#include <vector>
#include <algorithm>
#include <iterator>
#include <memory>
#include <iostream>
template <typename ...Arguments>
class CSignal
{
public:
typedef std::function<void (Arguments...)> SignalFunction;
public:
void connect(const SignalFunction& target)
{
m_connections.emplace_back(std::make_shared<SignalFunction>(target));
}
template <typename ...ActualArguments>
void invoke(ActualArguments&&... args) const
{
for (auto& connection: m_connections)
if (connection)
(*connection)(std::forward<ActualArguments>(args)...);
}
private:
std::vector<std::shared_ptr<SignalFunction>> m_connections;
};
struct A
{
void f() {std::cout << __FUNCTION__ << "\n";}
};
void test(std::shared_ptr<A> ptr)
{
if (ptr)
ptr->f();
}
int main()
{
CSignal<std::shared_ptr<A>> signal;
signal.connect(test);
signal.connect(test);
signal.invoke(std::make_shared<A>());
return 0;
}
Problem: test is called twice, and the second time it's called its parameter is empty pointer. Why?
If I remove std::forward the issue disappears, but that's not what I want.
Yes; std::forward does the same thing as std::move when ActualArguments is not a reference type.
In terms of expiration, forward needs to be treated the same as move. Generally you do not forward or move inside a loop.
If you want to move the parameter on the last loop iteration, you'll have to break it out of the loop. That probably means not using the range-for syntax. However, you might ask whether this is a worthwhile optimization, and consider saving it for later when more performance data are available.
I tried to define int Hash(string key) in the hash.cpp file but it is giving me the error "hash is ambiguous".
I am not sure why. I have distributed the #includes in many ways and it still isn't working.
[File: hash.cpp]
#include "hash.h"
using namespace std;
int hash::Hash(string key)
{
}
[File: hash.h]
#include<string>
#include<cstdlib>
#include <iomanip>
using namespace std;
#ifndef HASH_H
#define HASH_H
class hash
{
public:
int Hash(string key);
};
#endif
[FILE: main.cpp]
#include<iostream>
#include "hash.h"
using namespace std;
int main()
{
return 0;
}
The problem is that C++11 already comes with std::hash (reference link) which results in the experienced conflict. Either remove the using namespace std; and put your class into an own namespace or rename the class to something different.
I am using boost::serialization in my project. The project is large, and serializes my objects in several places. According to the documentation here, I should export my class with two separated step.
BOOST_EXPORT_KEY() in .h file, witch contains the declaration.
BOOST_EXPOET_IMPLEMENT() in .cpp file, witch contains the instantiation(definition) of the exporting.
hier.h the class hierarchy, there are 3 classes in the hierarchy.
/*
B <---+--- D1
|
+--- D2
*/
#include <boost/serialization/base_object.hpp>
class B {
public:
virtual ~B() {}
template < typename Ar >
void serialize(Ar& ar, const int) {
}
} ;
class D1 : public B {
public:
virtual ~D1() {}
template < typename Ar > void serialize(Ar& ar, const int) {
boost::serialization::base_object<B>(*this);
}
} ;
class D2 : public B {
public:
template < typename Ar > void serialize(Ar& ar, const int) {
boost::serialization::base_object<B>(*this);
}
virtual ~D2() {}
} ;
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT_KEY(B);
BOOST_CLASS_EXPORT_KEY(D1);
BOOST_CLASS_EXPORT_KEY(D2);
And a hier.cpp contains the implementation:
#include <boost/serialization/export.hpp>
#include "hier.h"
BOOST_CLASS_EXPORT_IMPLEMENT(D1);
BOOST_CLASS_EXPORT_IMPLEMENT(D2);
And a main.cpp use the serialization:
#include <iostream>
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include "hier.h"
int main(int argc, char* argv[])
{
B* d1 = new D1();
B* d2 = new D2();
std::ostringstream os;
boost::archive::text_oarchive oa (os);
oa & d1 & d2;
}
It compiled without any problem, but run it will cause:
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): unregistered class - derived class not registered or exported
Which means the derived class is not registered, means the registration in the hier.cpp is not working. But that is really strange, because:
If I register implementation is both main.cpp and hier.cpp, it issue duplicated definition while linking. Means the registration in hier.cpp is OK and is exposed into the linkers visibility., otherwise there will be no duplicated definition error.
If I register implementation only in main.cpp, it runs OK.
I am really confused in that situation. Any comment and suggestion is appreciated. Thanks in advance.
Before calling BOOST_CLASS_EXPORT_* you should include the archives which you want to use. The maсro then adds specific serialize-functions for the headers.
This means you should change your code in hier.cpp to the following:
#include <boost/serialization/export.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include "hier.h"
BOOST_CLASS_EXPORT_IMPLEMENT(D1);
BOOST_CLASS_EXPORT_IMPLEMENT(D2);
The code in hier.h changes accordingly:
#include <boost/serialization/export.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
BOOST_CLASS_EXPORT_KEY(B);
BOOST_CLASS_EXPORT_KEY(D1);
BOOST_CLASS_EXPORT_KEY(D2);
Sources:
Boost Serialization Documentation
PS:
I do not know if this is solving your problem, but I think it could be causing some trouble. I think it's worth a try.