No member named 'name' in namespace 'namespace' - c++

I can't for the life of me figure out why this error is being generated as I'm pretty sure the syntax is correct (obviously I'm wrong!). So I figured I'd see if anyone here could point it out for me.
main.cpp
#include "Object.h"
int main(){
out = json::readJSON(data_dir + "a2-empty_array_with_empty_object.json", e, debug);
}
Object.h
namespace json{
template<typename T>
std::string readJSON(std::string jsonFile, T& object, bool debug = false, char delimiter = ',') {}
}
I'm basically getting this error, when clearly the function is in the namespace. Why does it refer to the function as a member? Maybe there is something else going on here...
Error:
a2main.cpp:66:21: error: no member named 'readJSON' in namespace 'json'
out = json::readJSON(data_dir + "a2-cartoons.json", c, debug, '|');

You are probably not including the header files correctly.
The following code compiles (with both clang and gcc) and runs fine
#include <string>
namespace json
{
template<typename T>
std::string readJSON(std::string jsonFile, T& object, bool debug = false, char delimiter = ',')
{
return "Hello"; //This function should return a string
}
}
int main()
{
std::string data_dir = "test-";
int e = 3;
bool debug = false;
std::string out = json::readJSON(data_dir + "a2-empty_array_with_empty_object.json", e, debug);
return 0;
}
I hope this helps.

Related

Issue with LLVM JIT (LLJIT)

I am following a tutorial on making JIT compiler with LLVM (code is shown below and most recent version of LLVM is used). Everything works other than this line (if I comment this function, code compiles):
return (T)symbol.get().getAddress();
which gives the following error:
JIT.cpp:22:29: error: ‘std::remove_reference_t<llvm::orc::ExecutorAddr> {aka class llvm::orc::ExecutorAddr}’ has no member named ‘getAddress’
return (T)symbol.get().getAddress();
Code
#pragma once
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <memory>
#include <type_traits>
namespace FooLang
{
class JIT
{
private:
std::unique_ptr<llvm::orc::LLJIT> lljit;
public:
JIT(std::unique_ptr<llvm::orc::LLJIT> _lljit) : lljit(std::move(_lljit)) {}
void registerSymbols(
llvm::function_ref<llvm::orc::SymbolMap(llvm::orc::MangleAndInterner)> symbolMap) {
auto &mainJitDylib = this->lljit->getMainJITDylib();
llvm::cantFail(mainJitDylib.define(
absoluteSymbols(symbolMap(llvm::orc::MangleAndInterner(
mainJitDylib.getExecutionSession(), this->lljit->getDataLayout())))));
}
template <typename T, typename = std::enable_if_t<std::is_pointer<T>::value && std::is_function<std::remove_pointer_t<T>>::value>>
llvm::Expected<T> lookup(const std::string &name)
{
auto symbol = this->lljit->lookup(name);
if (!symbol)
{
return symbol.takeError();
}
return (T)symbol.get().getAddress();
}
template <typename T, typename = std::enable_if_t<std::is_function<T>::value>>
inline llvm::Expected<T *> lookup(const std::string &name)
{
return this->lookup<T *>(name);
}
static llvm::Expected<JIT> create(std::unique_ptr<llvm::Module> &module, std::unique_ptr<llvm::LLVMContext> &context)
{
auto lljit = llvm::orc::LLJITBuilder().create();
auto &jd = lljit.get()->getMainJITDylib();
jd.addGenerator(llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess('_')));
if (!lljit)
{
return lljit.takeError();
}
if (auto err = lljit.get()->addIRModule(llvm::orc::ThreadSafeModule(std::move(module), std::move(context))))
{
return std::move(err);
}
return JIT(std::move(lljit.get()));
}
};
} // namespace FooLang
And it is used like following:
int run(IRgen* ir_gen)
{
auto jit = JIT::create(ir_gen->module, ir_gen->llvm_context);
jit->registerSymbols(
[&](llvm::orc::MangleAndInterner interner) {
llvm::orc::SymbolMap symbolMap;
// Add symbols here
symbolMap[interner("printf")] = llvm::JITEvaluatedSymbol::fromPointer(printf);
return symbolMap;
});
auto entry = jit->lookup<int()>("main");
if (!entry)
{
llvm::errs() << entry.takeError();
return 1;
}
return entry.get()();
}
In a recent change auto symbol = this->llvmjit->lookup(name); will return an ExecutorAddr instead of a JITEvaluatedSymbols, see: https://reviews.llvm.org/rG16dcbb53dc7968a3752661aac731172ebe0faf64
Your pasted code returns a template parameter type T and doesn't show the caller so I can't see what you intend to return. My suggestion is that you probably want to use ExecutorAddr::toPtr but I can't be sure.

C++ I keep getting "was not declared in this scope error"

So, I have a header file and a class file. But when I compile puzzle.cpp, I keep getting get_solution was not declared in this scope. I don't get why that error occurs since its inside the same class so I can call any function inside the same class. Can anyone please help me on this? Thanks!
puzzle.h
#ifndef PUZZLE_H
#define PUZZLE_H
#include<iostream>
#include <string>
#include <vector>
class puzzle{
private:
std::string _solution;
std::vector<bool> _guesses;
public:
puzzle(std::string solution);
std::string get_solution(){return _solution;}
bool guess(char c);
bool solve(std::string proposed_solution);
std::string to_string();
};
#endif
puzzle.cpp
#include <iostream>
#include "puzzle.h"
#include <string>
#include <vector>
using namespace std;
puzzle::puzzle(std::string solution) {
_solution = solution;
for(int i = 0; i < 256; i++)
_guesses.push_back(false);
}
bool puzzle::guess(char c){
int num = c;
if(c<='z' || c>='a')
if(_guesses.at(c) == false){
_guesses.at(c) == true;
return true;
}
return false;
}
bool solve(string proposed_solution){
string test = get_solution();
if(proposed_solution.compare(test) == 0)
return true;
return false;
}
string to_string(){
int len = get_solution().length();
return "";
}
It looks like you've forgotten to make solve and to_string member functions:
Change
string to_string(){ ...
bool solve(string proposed_solution){ ...
^^^
To
string puzzle::to_string(){ ...
bool puzzle::solve(string proposed_solution){ ...
Your function bool solve(string proposed_solution) does not define a member function of puzzle but a "plain" function; Hence, get_solution(); within its body is not recognized as a member of puzzle, too. You'll have to write bool puzzle::solve(string proposed_solution) { ... and it should work.
solve and to_string are supposed to be methods, so you need to prefix them with the class' name followed by two colons (i.e., puzzle::):
bool puzzle::solve(string proposed_solution){
// Code ...
}
string puzzle::to_string(){
// Code ...
}

Enum in a class with strings

I'm trying to implement a class (C++) with an enum (with the permitted parameters). I got a working solution, but if I try to extend the functionality I get stuck.
Header data_location.hpp
class DataLocation
{
private:
public:
enum Params { model, period };
std::string getParamString(Params p);
};
Program data_location.cpp
string DataLocation::getParamString(Params p){
static const char * ParamsStrings[] = {"MODEL", "PERIOD"};
return ParamsStrings[p];
}
The array ParamsStrings should be generally available in the class, because I need a second method (with inverse function) returning the enum value given a string.
If I try to define the array in the header I get the error:
in-class initialization of static data member ‘const char* DataLocation::ParamsStrings []’ of incomplete type
Why is the type incomplete? The compiler is for sure able to counts the strings in the array, isn't it?
In case there is no way to get my code working, is there an other way? With 1) no XML; 2) no double definition of the strings; 3) not outside the class; 4) no in code programmed mapping.
In class (header) use keyword static and initialize it outside (.cpp) without the static keyword:
class DataLocation {
public:
enum Params { model, period };
string getParamString(Params p);
static const char* ParamsStrings[];
// ^^^^^^
};
const char* DataLocation::ParamsStrings[] = {"MODEL", "BLLBLA"};
//^^^^^^^^^^^^^^^^^^^^^^^^
The code you have posted is perfectly fine.
Here's the proof:
#include <iostream>
#include <string>
struct DataLocation
{
enum Params { model, period };
std::string getParamString(Params p){
static const char * ParamsStrings[] = {"MODEL", "PERIOD"};
return ParamsStrings[p];
}
};
int main()
{
auto a = DataLocation();
std::cout << a.getParamString(DataLocation::model) << std::endl;
return 0;
}
The error message you are getting is not to do with definition of a static data member in an inline function - that's allowed.
There's something else you're not showing us.
The main issue in my question (the second part) was that if I split the class in .hpp and .cpp the definition of the array (I mixed *char and string) has also to be split:
// data_location.hpp
class DataLocation {
static const char * ParamsStrings[];
}
// data_location.cpp
const char * ParamsStrings[] = {"MODEL", "PERIOD"};
At the end I introduced a consistency check to be sure that the number of values in enum growths as the number of strings. Because the array in C++ is somehow limited I had to go for a std::vector (to get the size).
Code for data_location.hpp
#ifndef DATA_LOCATION_HPP_
#define DATA_LOCATION_HPP_
#include <string>
#include "utils/dictionary.hpp"
extern const char* ENV_DATA_ROOT;
struct EDataLocationInconsistency : std::runtime_error
{
using std::runtime_error::runtime_error;
};
struct EDataLocationNotValidParam : std::runtime_error
{
using std::runtime_error::runtime_error;
};
class DataLocation
{
private:
std::string mRootLocation;
static const std::vector<std::string> msParamsStrings;
static bool msConsistenceCheckDone;
public:
DataLocation();
std::string getRootLocation();
std::string getLocation(Dictionary params);
enum Params { model, period, LAST_PARAM};
std::string Param2String(Params p);
Params String2Param(std::string p);
};
#endif
Code for data_location.cpp
#include "data_location.hpp"
#include <string>
#include <cstdlib>
using namespace std;
const char* ENV_DATA_ROOT = "DATA_ROOT";
bool DataLocation::msConsistenceCheckDone = false;
DataLocation::DataLocation() {
mRootLocation = std::getenv(ENV_DATA_ROOT);
if (not msConsistenceCheckDone) {
msConsistenceCheckDone = true;
if (LAST_PARAM+1 != msParamsStrings.size()) {
throw(EDataLocationInconsistency("DataLocation: Check Params and msParamsStrings"));
}
}
}
string DataLocation::getRootLocation() {
return mRootLocation;
}
string DataLocation::getLocation(Dictionary params) {
// to do
return "";
}
const vector<string> DataLocation::msParamsStrings = { "MODEL", "PERIOD", ""};
string DataLocation::Param2String(Params p) {
if (p>=msParamsStrings.size()) {
throw(EDataLocationNotValidParam("Parameter not found"));
}
return msParamsStrings[p];
}
DataLocation::Params DataLocation::String2Param(string p) {
for (int i = 0; i < msParamsStrings.size(); i++) {
if (p == msParamsStrings[i])
return (Params)i;
}
throw(EDataLocationNotValidParam("Parameter not found"));
}
And also a unit test:
#include <boost/test/unit_test.hpp>
#include "data_location.hpp"
#include <string>
using namespace std;
BOOST_AUTO_TEST_SUITE( data_location )
BOOST_AUTO_TEST_CASE(data_location_1) {
DataLocation dl;
auto s = dl.getRootLocation();
BOOST_CHECK_EQUAL(s, "/home/tc/data/forex" );
BOOST_CHECK_EQUAL(dl.Param2String(DataLocation::period),"PERIOD");
BOOST_CHECK_EQUAL(dl.String2Param("PERIOD"),DataLocation::period);
BOOST_CHECK_THROW(dl.String2Param("SOMETHING"), EDataLocationNotValidParam);
BOOST_CHECK_THROW(dl.Param2String((DataLocation::Params)100), EDataLocationNotValidParam);
}
BOOST_AUTO_TEST_SUITE_END()
C++ is very picky about what it will let you initialize inside of a class definition; there are some particularly non-intuitive rules surrounding static members. It all has to do with the ODR, and why all the rules are the way they are is not especially important.
To cut to the chase, making your array a static constexpr const member should shut the compiler up. With the C++11 standard, the restrictions were relaxed a bit, and one of the new stipulations was that static constexpr members can be initialized inline. This is perfect for your application, since the strings in your array are compile-time constants.
The recent g++ compiler which support C++0x or later compiles thus code. Pure C compile compiles, too. Because strings in initialization like {"MODEL", "PERIOD"}; implemented as const char * pointer to the char array.

Using Templates Inside a Namespace

I asked this question yesterday and thought I got to the bottom of the problem... But alas it seems to be something else. I haven't the faintest idea what the issue could be, but this error is being thrown using the the following code:
Error:
a2main.cpp:36:21: error: no member named 'readJSON' in namespace 'json'
out = json::readJSON(data_dir + "a2-empty_object.json", e, debug);
~~~~~~^
main.cpp
#include <iostream>
#include <string>
#include "Object.h"
int main(){
std::string out;
out = json::readJSON(data_dir + "a2-empty_object.json", e, debug);
}
Object.h
#ifndef _JSON_READER_H_
#define _JSON_READER_H_
namespace json{
enum JSON_TYPE {
UNKNOWN, EMPTY, ARRAY_OPEN, ARRAY_CLOSE, OBJECT_OPEN, OBJECT_CLOSE, NV_PAIR
};
std::string trim(const std::string& str);
std::string trim(const std::string& str, char c);
std::string getName(const std::string& str);
std::string getValue(const std::string& str);
JSON_TYPE get_json_type(std::string s);
template<typename T>
List <T, OBJECTS_PER_JSON_FILE>* deserializeJSON(std::string filename, T obj, bool debug) {
std::ifstream fin(filename);
if (fin.fail()){
throw std::string("Couldn't open: " + filename);
}
std::string fline, line, n,v;
bool done=false;
auto list = new List <T, OBJECTS_PER_JSON_FILE>();
return list;
}
template<typename T>
std::string readJSON(std::string jsonFile, T& object, bool debug = false, char delimiter = ',') {
std::string string_of_values = "test";
return string_of_values;
}
}
#endif
Why is it throwing an error that the function is not in the namespace? It seems rather odd. Could it be a template issue? Thanks!
EDIT:
In file included from a2main.cpp:13:
./JSONReader.h:60:2: error: unknown type name 'List'
List <T, OBJECTS_PER_JSON_FILE>* deserializeJSON(std::string filename, T obj, bool debug) {
^
./JSONReader.h:60:7: error: expected unqualified-id
List <T, OBJECTS_PER_JSON_FILE>* deserializeJSON(std::string filename, T obj, bool debug) {
^

Using template in c++ - Returning values from method

I wanna a method that receives a generic type, and a generic type (that's defined in run time). In the example there's if I'm using a string type, It needs to return the first param lenght (in string); If I'm using a int type, needs to return the biggest (int integer).
Have a look:
#include "stdafx.h"
#include <sstream>
#include <iostream>
#include <conio.h>
#include <sstream>
#include <string>
#include <atldbcli.h>
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
no_namespace rename("EOF", "EndOfFile")
using namespace std;
class Test
{
public:
template<class T>
T returnVal(T valueOne, T valueTwo);
};
template<class T>
T Test::returnVal(T valueOne, T valueTwo)
{
if(typeid(valueOne) == typeid(string))
{
string teste = valueOne;
int testeInt = teste.size();
ostringstream testeString;
testeString << testeInt;
teste = testeString.str();
return teste;
}
else
return valueOne > valueTwo? valueOne:valueTwo;
}
int main()
{
string reference = "stringVal";
Test ref;
cout << ref.returnVal<string>(reference, "asasas") << endl;
cout << ref.returnVal<int>(10, 485);
getch();
return 0;
}
However, when the main function calls ref.returnVal(10, 485); it's show a message error: 'return' : cannot convert from 'std::string' to 'int'
Does anybody know what's wrong?
Thanks
this is not the proper way to do what you want. You can't use typeid to switch between types and do different operations, because all the different paths still have to be compiled, and inside your if you do return a string while your method returns an int.
google template specialization, that's what you need I guess...
#include <string>
template <class T>
int returnVal(T valueOne, T valueTwo);
template <>
int returnVal<std::string>(std::string valueOne, std::string valueTwo)
{
return (int)valueOne.length();
}
template <>
int returnVal<int>(int valueOne, int valueTwo)
{
return std::max(valueOne, valueTwo);
}
int main()
{
int x = returnVal(std::string("Hello"), std::string("World!"));
int y = returnVal(1,2);
return 0;
}
Unless I'm misunderstanding you, you could achieve this with template specialization?
All previous answers clearly identify the problem. As for a better way to do it:
class Test
{
public:
string returnVal(string valueOne, string valueTwo)
{
string teste = valueOne;
int testeInt = teste.size();
ostringstream testeString;
testeString << testeInt;
teste = testeString.str();
return teste;
}
int returnVal(int valueOne, int valueTwo)
{
return valueOne > valueTwo? valueOne:valueTwo;
}
};
If you instantiate your template for type int, it looks like this:
int Test::returnVal(int valueOne, int valueTwo)
{
if(typeid(valueOne) == typeid(string)) // This will be false
{
string teste = valueOne;
int testeInt = teste.size();
ostringstream testeString;
testeString << testeInt;
teste = testeString.str();
return teste;
}
else
return valueOne > valueTwo? valueOne:valueTwo;
}
The problem is that the then-clause of your if returns a string even though the return type of the function is int. The fact that the then-clause will never execute because typeif(valueOne) can't possible be string doesn't matter because the type checker does not care about that. All he sees is a return statement that returns a string, so that's an error.
To do what you want, you should simply overload your function for strings and remove all the string-specific code from the templated function.