I have a class with a static std::map member variable that maps chars to a custom type Terrain. I'm attempting to fill this map in the class's implementation file, but I get several errors. Here's my header file:
#ifndef LEVEL_HPP
#define LEVEL_HPP
#include <bitset>
#include <list>
#include <map>
#include <string>
#include <vector>
#include "libtcod.hpp"
namespace yarl
{
namespace level
{
class Terrain
{
// Member Variables
private:
std::bitset<5> flags;
// Member Functions
public:
explicit Terrain(const std::string& flg)
: flags(flg) {}
(...)
};
class Level
{
private:
static std::map<char, Terrain> terrainTypes;
(...)
};
}
}
#endif
and here's my implementation file:
#include <bitset>
#include <list>
#include <map>
#include <string>
#include <vector>
#include "Level.hpp"
#include "libtcod.hpp"
using namespace std;
namespace yarl
{
namespace level
{
/* fill Level::terrainTypes */
map<char,Terrain> Level::terrainTypes['.'] = Terrain("00001"); // clear
map<char,Terrain> Level::terrainTypes[','] = Terrain("00001"); // clear
map<char,Terrain> Level::terrainTypes['\''] = Terrain("00001"); // clear
map<char,Terrain> Level::terrainTypes['`'] = Terrain("00001"); // clear
map<char,Terrain> Level::terrainTypes[178] = Terrain("11111"); // wall
(...)
}
}
I'm using g++, and the errors I get are
src/Level.cpp:15: error: conflicting declaration ‘std::map, std::allocator > > yarl::level::Level::terrainTypes [46]’
src/Level.hpp:104: error: ‘yarl::level::Level::terrainTypes’ has a previous declaration as ‘std::map, std::allocator > > yarl::level::Level::terrainTypes’
src/Level.cpp:15: error: declaration of ‘std::map, std::allocator > > yarl::level::Level::terrainTypes’ outside of class is not definition
src/Level.cpp:15: error: conversion from ‘yarl::level::Terrain’ to non-scalar type ‘std::map, std::allocator > >’ requested
src/Level.cpp:15: error: ‘yarl::level::Level::terrainTypes’ cannot be initialized by a non-constant expression when being declared
I get a set of these for each map assignment line in the implementation file. Anyone see what I'm doing wrong? Thanks for your help.
You can initialize static members outside of functions, but you can't perform arbitrary operations.
You could use a function to initialize the members:
namespace {
std::map<char, Terrain> initTerrainTypes() {
std::map<char, Terrain> m;
m['.'] = Terrain("00001");
// ...
return m;
}
}
map<char,Terrain> Level::terrainTypes = initTerrainTypes();
Or you could use initialization utilities like Boost.Assign:
map<char,Terrain> Level::terrainTypes = boost::assign::map_list_of
('.', Terrain("00001"))
// ...
(178, Terrain("11111"));
Related
I have written a class called ProcessingThread, where I pass a boost:circular buffer with the help of a shared pointer:
#ifndef PROCESSING_THREAD_H__
#define PROCESSING_THREAD_H__
#ifndef BOOST_ALL_DYN_LINK
#define BOOST_ALL_DYN_LINK
#endif
#include <bitset>
#include <thread>
#include "boost/circular_buffer.hpp"
using namespace boost;
class ProcessingThread{
public:
ProcessingThread(std::shared_ptr<circular_buffer<std::bitset<32>>> cBuffer) : circularBuffer(cBuffer), processingThread() {}
~ProcessingThread();
void start();
private:
void threadMain();
std::shared_ptr<circular_buffer<std::bitset<32>>> circularBuffer;
std::thread processingThread;
};
#endif
With the following implementation:
#include "processingThread.h"
ProcessingThread::~ProcessingThread(){
if(this->processingThread.joinable()){
this->processingThread.join();
}
}
void ProcessingThread::start(){
this->processingThread = std::thread(&ProcessingThread::threadMain, this);
}
void ProcessingThread::threadMain(){
//TODO some stuff
}
And finally, I create a class instance and call start(). This is where the error appears:
#include <bitset>
#include <iostream>
#include "boost/circular_buffer.hpp"
#include "processingThread.h"
using namespace boost;
using namespace std;
int main(){
circular_buffer<bitset<32>> circularBuffer(4000);
ProcessingThread processingThread(std::shared_ptr<circular_buffer<bitset<32>>>(circularBuffer));
processingThread.start(); <--- error
}
The error says:
error: request for member ‘start’ in ‘processingThread’, which is of non-class type ‘ProcessingThread(std::shared_ptr<boost::circular_buffer<std::bitset<32ul> > >)’
Which is the typical error of using '.' instead of '->' when using creating the class dynamically, which is not the case.
What am I missing here?
You defined a function!
ProcessingThread processingThread(
std::shared_ptr<circular_buffer<bitset<32>>>(circularBuffer) );
is a function which has one argument of type std::shared_ptr<circular_buffer<bitset<32>>>. Easy solution:
ProcessingThread processingThread(
std::shared_ptr<circular_buffer<bitset<32>>> { circularBuffer } );
I have implemented a class buffer_manger.The header file (.hpp) and (.cpp) files are given below.
buffer_manager.hpp
#ifndef BUFFER_MANAGER_H
#define BUFFER_MANAGER_H
#include <iostream>
#include <exception>
#include <boost/array.hpp>
#include <boost/algorithm/hex.hpp>
#include <algorithm>
#include <iomanip>
class buffer_manager
{
public:
typedef boost::array<unsigned char, 4096> m_array_type;
m_array_type recv_buf;
buffer_manager();
~buffer_manager();
std::string message_buffer(m_array_type &recv_buf);
m_array_type get_recieve_array();
private:
std::string message;
};
#endif //BUFFER_MANAGER_H
buffer_manager.cpp
#include <iostream>
#include <boost/array.hpp>
#include <boost/algorithm/hex.hpp>
#include <algorithm>
#include "buffer_manager.hpp"
buffer_manager::buffer_manager()
{
}
buffer_manager::~buffer_manager()
{
}
std::string buffer_manager::message_buffer(m_array_type &recv_buf)
{
boost::algorithm::hex(recv_buf.begin(), recv_buf.end(), back_inserter(message));
return message;
}
m_array_type buffer_manager::get_recieve_buffer()
{
return recv_buf;
}
The problem is I have defined a type m_array_type insde the class buffer_manager. I have also declared a variable of that type named recv_buf
I tried to implement an accessor function for that member variable. I get the error that
buffer_manager.cpp:22:1: error: ‘m_array_type’ does not name a type
m_array_type buffer_manager::get_recieve_buffer()
How do I get the buffer_manager.cpp to recognize the type m_array_type
You simply need to qualify it:
buffer_manager::m_array_type buffer_manager::get_recieve_buffer()
^^^^^^^^^^^^^^^^
{
return recv_buf;
}
Everything after the member function name will get looked up in the context of the class, but not the return type.
As a side-note, do you really want to return it by-value? Perhaps m_array_type&?
m_array_type buffer_manager::get_recieve_buffer()
The problem here is that when the compiler sees m_array_type it doesn't know that it's compiling a member function. So you have to tell it where that type is defined:
buffer_manager::m_array_type buffer_manager::get_recieve_buffer()
What I have is :
#include "thread.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
vector<Requester*> requesters; //global
struct Requester {
vector<thread> t;
vector<int> tracks;
};
Then in my function I have:
void serviceQ(){
vector<Requester*> test = requesters; //error
}
The error is:
no suitable user-defined conversion from "std::vector<<error-type> *, std::allocator<<error-type> *>>" to "std::vector<Requester *, std::allocator<Requester *>>" exists
I'm very confused as to why this is. Why does it call my global variable an error type in the function? If I were to do something like:
void serviceQ(){
vector<Requester*> test;
//do some stuff
vector<Requester*> result = test; //no error
}
Then there is no error.
You need to define
vector<Requester*> requesters; //global
after the definition of struct Requester, as otherwise the compiler doesn't know what Requester* means when it attempts to define the corresponding vector<Requester*>. Alternatively, you can just declare
struct Requester;
above the line vector<Requester*> requesters;.
I am trying to have a static method return a shared_ptr.
It is not compiling and is giving template argument 1 is invalid.
I can not figure out why this is.
Also, stack overflow says my post is mostly code and that I should add more detail. I don't know why this is, as being concise never hurt anyone. My problem is clear cut and and can be detailed easily.
Compiler error
src/WavFile.cpp:7:24: error: template argument 1 is invalid
std::shared_ptr<WavFile> WavFile::LoadWavFromFile(std::string filename)
WavFile.cpp
#include "WavFile.h"
#include "LogStream.h"
#include "assert.h"
using namespace WavFile;
std::shared_ptr<WavFile> WavFile::LoadWavFromFile(std::string filename)
{
ifstream infile;
infile.open( filname, ios::binary | ios::in );
}
WavFile.h
#pragma once
#ifndef __WAVFILE_H_
#define __WAVFILE_H_
#include <fstream>
#include <vector>
#include <memory>
namespace WavFile
{
class WavFile;
}
class WavFile::WavFile
{
public:
typedef std::vector<unsigned char> PCMData8_t;
typedef std::vector<unsigned short int> PCMData16_t;
struct WavFileHeader {
unsigned int num_channels;
unsigned int sample_rate;
unsigned int bits_per_sample;
};
static std::shared_ptr<WavFile> LoadWavFromFile(std::string filename);
private:
WavFile(void);
private:
WavFileHeader m_header;
PCMData16_t m_data16;
PCMData8_t m_data8;
};
#endif
Change the namespace name to something else. Now it clashes with the class' name, since you are using namespace WavFile;. Simple example that illustrates the error:
#include <iostream>
#include <memory>
namespace X // changing this to Y makes the code compilable
{
class X{};
}
using namespace X; // now both class X and namespace X are visible
std::shared_ptr<X> v() // the compiler is confused here, which X are you referring to?
{
return {};
}
int main() {}
If you insist to have the namespace named as the class, then get rid of the using namespace X; and qualify the type, std::shared_ptr<WafFile::WavFile>.
here is my header level.h:
#ifndef LEVEL_H_
#define LEVEL_H_
#include <string>
#include <map>
#include <queue>
#include <list>
typedef struct {
std::string title;
int stepsAmount;
std::queue <std::list <char> > steps;
std::queue <std::map <std::string, int> > stepsOptions;
} Level;
std::string getCurrentStepExpression(Level* level);
#endif
And my level.cpp:
#include "level.h"
std::string getCurrentStepExpression(Level* level) {
std::string result;
if (level)
result = level->stepExpressions.front();
return result;
}
Everything seems okay, but compiller says:
..\level.cpp: In function 'std::string getCurrentStepExpression(Level*)':
..\level.cpp:12:19: error: 'struct Level' has no member named 'stepExpressions'
why it doesn't see my struct's fields?
you need to add a stepExpressions member or stepExpressions() method to your struct Level and pass in some index to lookup in steps.
struct Level {
std::string title;
int stepsAmount;
std::queue <std::list <char> > steps;
std::queue <std::map <std::string, int> > stepsOptions;
/* add the method stepExpressions to your class */
std::list& stepExpressions(int step);
};
stepExpressions is not part of your struct.
Try adding it.