Can't get_value() from Boost property tree map value in VS2019 - boost

I followed this link to extract a Boost property tree value.
Extracting STL Map from Boost Property Tree
I don't have library fmt installed so just modified the output function from the original code. The code works fine in g++. But when testing in VS2019, the error "identifier "" is undefined" kept popping.
#include <boost/property_tree/ptree.hpp>
#include <map>
#include <iostream>
using boost::property_tree::ptree;
int main() {
ptree pt;
pt.put("keyA", "valueA-1");
pt.put("keyB", "valueB");
pt.put("keyC", "valueC");
pt.add("keyA", "valueA-2"); // not replacing same key
std::map<std::string, ptree> m(pt.begin(), pt.end());
std::multimap<std::string, ptree> mm(pt.begin(), pt.end());
std::map<std::string, std::string> dict;
for (auto& [k,v]: pt) { // THIS LINE HAS ERROR!
dict.emplace(k, v.get_value<std::string>());
}
for (auto elem : dict) {
std::cout << elem.first << " " << elem.second << std::endl;
}
return 0;
}
I don't see anything wrong with this specified line so I must have missed some switches or config in VS2019?

I found the answer myself after realizing VS2019 uses C++14 by default. The specified line: "auto& [k, v] : pt" needs some C++17 feature. So go to Project Setting --> Configuration Properties --> General --> C++ Language Standard --> Change to ISO C++17 Standard (/std:c++17).
Then the code works fine

Related

why the output of the auto variable displays something not related to type?

I tried a example on Auto for variable initialization and STL in C++. For normal variable, type was printed using : typeid(var_name).name() to print i (integer) / d(float) / pi(pointer) which works fine.
But while working on STL,
`#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<string> st;
st.push_back("geeks");
st.push_back("for");
for (auto it = st.begin(); it != st.end(); it++)
cout << typeid(it).name() << "\n";
return 0;
}
`
which gives output like,
`N9__gnu_cxx17__normal_iteratorIPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIS6_SaIS6_EEEE
N9__gnu_cxx17__normal_iteratorIPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIS6_SaIS6_EEEE`
and I am unable to understand the output logic behind it, can anyone explain why it is giving output like this? and thanks in advance
That's the "name mangled" version of the name of the type of it. typeinfo::name() is not required by the standard to return a name in human-readable format (a shortcoming IMHO) and GCC doesn't do so.
To get the actual, human-readable name, you need to call the abi::__cxa_demangle() function provided by GCC, but note that this is non-portable so if your project needs to work on different compilers you'll need to wrap it appropriately.

libxl library use in c++

When I create a project visual studio 2015 I can work this libxl library hovewer I could not be able to work that library on visual studio qt gui application project.
I try everything whatever I know.
#include "stdafx.h"
#include "QtGuiApplication5.h"
#include <QtWidgets/QApplication>
#include <qapplication.h>
#include <qpushbutton.h>
#include <iostream>
#include <conio.h>
#include "libxl.h"
using namespacenclude <Qt libxl;
using namespace std;
int main(int argc, char *argv[])
{
Book* book = xlCreateBook();
if (book)
{
if (book->load(L"..\\Lab_Bus Datebase.xlsx"))
{
Sheet* sheet = book->getSheet(0);
if (sheet)
{
const wchar_t* s = sheet->readStr(2, 1);
if (s) std::wcout << s << std::endl << std::endl;
}
}
else
{
std::cout << "At first run generate !" << std::endl;
}
book->release();
}
std::cout << "\nPress any key to exit...";
_getch();
QApplication a(argc, argv);
QtGuiApplication5 w;
w.show();
return a.exec();
}
Link2019 error: Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol __imp_xlCreateBookW referenced in function main QtGuiApplication5
link1120 error: Severity Code Description Project File Line Suppression State
Error LNK1120 1 unresolved externals QtGuiApplication5 C
You need to configure visual studio project properties to use required lib. Refer this link for the same.
You are using .xlsx file so instead of xlCreateBook use xlCreateXMLBook. Apart from this you need to use using namespace libxl;as well
Below are Factory functions:
Book* xlCreateBook()
Create a binary book instance for xls format. This function should be called first for receiving a book pointer. This function and other classes are in libxl namespace.
Book* xlCreateXMLBook()
Create a xml book instance for xlsx format. This function should be called first for receiving a book pointer. This function and other classes are in libxl namespace.
See below image above code works fine at my machine.

C++ std::unordered_map key custom hashing

I've got the following test.cpp file
#include <string>
#include <functional>
#include <unordered_map>
#include <iostream>
class Mystuff {
public:
std::string key1;
int key2;
public:
Mystuff(std::string _key1, int _key2)
: key1(_key1)
, key2(_key2)
{}
};
namespace std {
template<>
struct hash<Mystuff *> {
size_t operator()(Mystuff * const& any) const {
size_t hashres = std::hash<std::string>()(any->key1);
hashres ^= std::hash<int>()(any->key2);
std::cout << "Hash for find/insert is [" << hashres << "]" << std::endl;
return (hashres);
}
};
}; /* eof namespace std */
typedef std::unordered_map<Mystuff *, Mystuff *>mystuff_map_t;
mystuff_map_t map;
int insert_if_not_there(Mystuff * stuff) {
std::cout << "Trying insert for " << stuff->key1 << std::endl;
if (map.find(stuff) != map.end()) {
std::cout << "It's there already..." << std::endl;
return (-1);
} else {
map[stuff] = stuff;
std::cout << "Worked..." << std::endl;
}
return (0);
}
int main(){
Mystuff first("first", 1);
Mystuff second("second", 2);
Mystuff third("third", 3);
Mystuff third_duplicate("third", 3);
insert_if_not_there(&first);
insert_if_not_there(&second);
insert_if_not_there(&third);
insert_if_not_there(&third_duplicate);
}
You can compile with g++ -o test test.cpp -std=gnu++11.
I don't get what I'm doing wrong with it: the hash keying algorithm is definitely working, but for some reason (which is obviously in the - bad - way I'm doing something), third_duplicate is inserted as well in the map, while I'd wish it wasn't.
What am I doing wrong?
IIRC unordered containers need operator== as well as std::hash. Without it, I'd expect a compilation error. Except that your key is actually MyStuff* - the pointer, not the value.
That means you get the duplicate key stored as a separate item because it's actually not, to unordered_map, a real duplicate - it has a different address, and address equality is how unordered_map is judging equality.
Simple solution - use std::unordered_map<Mystuff,Mystuff> instead. You will need to overload operator== (or there's IIRC some alternative template, similar to std::hash, that you can specialize). You'll also need to change your std::hash to also accept the value rather than the pointer.
Don't over-use pointers in C++, especially not raw pointers. For pass-by-reference, prefer references to pointers (that's a C++-specific meaning of "reference" vs. "pointer"). For containers, the normal default is to use the type directly for content, though there are cases where you might want a pointer (or a smart pointer) instead.
I haven't thoroughly checked your code - there may be more issues than I caught.

Default value for struct member in c++

It seems that we can not give a default value for struct members in c++,but I find that code as below can compile and run, why? Am I missing something?
struct Type {
int i = 0xffff;
};
Program:
#include <iostream>
using namespace std;
struct Type {
int i = 0xffff;
};
int main() {
// your code goes here
Type val;
std::cout << val.i << std::endl;
return 0;
}
It is going to depend on the compiler you use.
For gcc and clang you need to pass the flag -std=c++11 to the compiler.
Support for member initializer and other c++11 features:
gcc since 4.7. See here.
clang since 3.0. See here.
Visual studio compiler in its 2013 version. See here.
This is correct and introduced in C++11 standard. This concept is known as in-class member initializer
You can check Stroustrup FAQ link on this concept:
http://www.stroustrup.com/C++11FAQ.html#member-init

Visual Studio Intel Threading Building Blocks DLL error

I am using an example of Intel TBB code I found on SO:
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/task_scheduler_init.h"
#include <iostream>
#include <vector>
struct mytask {
mytask(size_t n)
:_n(n)
{}
void operator()() {
for (int i=0;i<1000000;++i) {} // Deliberately run slow
std::cerr << "[" << _n << "]";
}
size_t _n;
};
struct executor
{
executor(std::vector<mytask>& t) :_tasks(t)
{}
executor(executor& e,tbb::split) :_tasks(e._tasks)
{}
void operator()(const tbb::blocked_range<size_t>& r) const {
for (size_t i=r.begin();i!=r.end();++i)
_tasks[i]();
}
std::vector<mytask>& _tasks;
};
int main(int,char**) {
tbb::task_scheduler_init init; // Automatic number of threads
// tbb::task_scheduler_init init(2); // Explicit number of threads
std::vector<mytask> tasks;
for (int i=0;i<1000;++i){
tasks.push_back(mytask(i));
}
executor exec(tasks);
tbb::parallel_for(tbb::blocked_range<size_t>(0,tasks.size()),exec);
std::cerr << std::endl;
return 0;
}
The code builds fine, but when I go to run I get the error:
The program can't start because tbb_debug.dll is missing from your
computer. Try reinstalling the program to fix this problem.
I think this is probably the path I need to set somewhere within VS2012:
C:\Program Files (x86)\Intel\Composer XE 2013 SP1\redist\ia32\tbb\vc11
because it contains tbb_debug.dll.
Where does this path need to be set?
EDIT: I tried setting in the "Executable directories" path section but that didnt work.
In solution explorer, right click the project and open "Properties"
Open "Configuration Properties" -> "Debugging".
In the "Environment" line, add "PATH=C:\Program Files (x86)\Intel\Composer XE 2013"
Make sure "Merge Environment" is set to "Yes".

Resources