Well this is my first experience with lambda, and I know I might be misusing this feature but I'm wondering why should I get a compile error?
GameMap::MoveDirection AIPlayer::getSafeRouteTo(const GameMap::PlayerInfo& s, const Point& e)
{
struct node : public Point
{
GameMap::MoveDirection parent;
float d;
node():Point(){};
node(Point p) : Point(p)
{
};
};
auto lambdaFunction = [this,&e](node&left,node&right)->bool
{
return this->getDistance(left,e) + left.d < this->getDistance(right,e) + right.d;
};
priority_queue<node,vector<node>, decltype(lambdaFunction)> Q;
//do stuff
return GameMap::MD_None;
}
and for the sake of argument let me say that MoveDirection is an enum, and Point does have a default constructor. as I commented by removing that specific line I don't get the error but I really need it to be there. here are the errors VC2010 is generating:
d:\program files (x86)\microsoft visual studio 10.0\vc\include\queue(225): error C2512: '`anonymous-namespace'::<lambda0>' : no appropriate default constructor available
1> d:\program files (x86)\microsoft visual studio 10.0\vc\include\queue(223) : while compiling class template member function 'std::priority_queue<_Ty,_Container,_Pr>::priority_queue(void)'
1> with
1> [
1> _Ty=AIPlayer::getSafeRouteTo::node,
1> _Container=std::vector<AIPlayer::getSafeRouteTo::node>,
1> _Pr=`anonymous-namespace'::<lambda0>
1> ]
1> c:\users\ali\documents\visual studio 2010\projects\bokhorbokhor\aiplayer.cpp(147) : see reference to class template instantiation 'std::priority_queue<_Ty,_Container,_Pr>' being compiled
1> with
1> [
1> _Ty=AIPlayer::getSafeRouteTo::node,
1> _Container=std::vector<AIPlayer::getSafeRouteTo::node>,
1> _Pr=`anonymous-namespace'::<lambda0>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The lambda is not default constructible. You have to pass it to this constructor of the priority_queue:
explicit priority_queue(const Compare& x = Compare(), Container&& = Container());
Like this:
priority_queue<node,vector<node>, decltype(lambdaFunction)> Q ( lambdaFunction );
Related
I am new to C++ so this is likely a simple mistake but this code is giving me problems for hours now. I am really just not sure what to try next.
EratosthenesHashMap.h
#pragma once
#include <unordered_map>
#include <boost/functional/hash.hpp>
#include "SieveOfEratosthenes.h"
template<class T>
class EratosthenesHashMap
{
public:
EratosthenesHashMap(SieveOfEratosthenes& sieve);
~EratosthenesHashMap();
unsigned int addValue(T& value);
unsigned int getPrime(T& value) const;
private:
SieveOfEratosthenes *sieve;
std::unordered_map<T, unsigned int, boost::hash<T>> valueMap;
};
EratosthenesHashMap.cpp
#include "EratosthenesHashMap.h"
EratosthenesHashMap<class T>::EratosthenesHashMap(SieveOfEratosthenes& sieve)
{
this->sieve = &sieve;
};
unsigned int EratosthenesHashMap<T>::addValue(T& value)
{
return 0;
}
unsigned int EratosthenesHashMap<T>::getPrime(T& value) const
{
return 0;
}
Error:
EratosthenesHashMap.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\utility(331,10): error C2079: 'std::pair<const T,unsigned int>::first' uses undefined class 'T'
1> with
1> [
1> T=T
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xhash(305): message : see reference to class template instantiation 'std::pair<const T,unsigned int>' being compiled
1> with
1> [
1> T=T
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xhash(304): message : while compiling class template member function 'void std::_Hash_vec<std::allocator<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<_Ty>>>>>::_Tidy(void) noexcept'
1> with
1> [
1> _Ty=std::pair<const T,unsigned int>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xhash(313): message : see reference to function template instantiation 'void std::_Hash_vec<std::allocator<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<_Ty>>>>>::_Tidy(void) noexcept' being compiled
1> with
1> [
1> _Ty=std::pair<const T,unsigned int>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xhash(1933): message : see reference to class template instantiation 'std::_Hash_vec<std::allocator<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<_Ty>>>>>' being compiled
1> with
1> [
1> _Ty=std::pair<const T,unsigned int>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\unordered_map(69): message : see reference to class template instantiation 'std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>' being compiled
1> with
1> [
1> _Kty=T,
1> _Ty=unsigned int,
1> _Hasher=boost::hash<T>,
1> _Keyeq=std::equal_to<T>,
1> _Alloc=std::allocator<std::pair<const T,unsigned int>>
1> ]
1>C:\Users\jpsie\source\repos\EratosthenesContainer\EratosthenesContainer\EratosthenesHashMap.h(20): message : see reference to class template instantiation 'std::unordered_map<T,unsigned int,boost::hash<T>,std::equal_to<T>,std::allocator<std::pair<const T,unsigned int>>>' being compiled
1> with
1> [
1> T=T
1> ]
I am trying to create a hashmap as a member variable with key type T, value type unsigned int, and I am using the boost library for a hash function.
It is rather difficult to have a template class split between header file and .cpp file and be easy to consume by callers. Instead, inline your entire template class in EratosthenesHashMap.h:
template<class T>
class EratosthenesHashMap
{
public:
EratosthenesHashMap(SieveOfEratosthenes& sieve)
{
this->sieve = &sieve;
}
~EratosthenesHashMap()
{
}
unsigned int addValue(T& value)
{
return 0;
}
unsigned int getPrime(T& value) const
{
return 0;
}
private:
SieveOfEratosthenes* sieve;
std::unordered_map<T, unsigned int, boost::hash<T>> valueMap;
};
The way to define a member of a template class is
template<class T>
EratosthenesHashMap<T>::EratosthenesHashMap(SieveOfEratosthenes& sieve)
{
this->sieve = &sieve;
};
On top of that, you should probably defined the templates in the header file, because otherwise they will only be usable in the same cpp file.
See Why can templates only be implemented in the header file?
The reason your code doesn't compile is that you can't break a class template into a .h file and .cpp file in the typical way.
Say you have a main.cpp file that uses EratosthenesHashMap<int> and you have EratosthenesHashMap broken into a .h and a .cpp as in your question, then main.cpp gets compiled completely independently of EratosthenesHashMap.cpp and needs to be able to link to an implementation of EratosthenesHashMap<int> but EratosthenesHashMap.cpp does not know anything about what types it will be applied to so this is impossible.
EratosthenesHashMap.cpp does not define a class; it defines a template; it can't be compiled into an object file that can be linked against.
Typically you use templates by providing a full implementation in a header for this reason.
I've implemented a custom container class together with its iterator, and trying to use a for_each on it. Everything compiles fine in VC6, online cpp.sh and MSVC15, the latter only in release: when in debug I got a series of errors I report, under, the oversimplified version of my code.
struct Functor {
void operator()(int&) {}
} func;
struct Container {
typedef int value_type;
struct iterator {
bool operator!=(iterator const&) { return true; }
iterator& operator++() { return *this; }
value_type& operator*() { return i; } //this is just to compile, not for real
int i; //this is just to compile, not for real
};
iterator begin() { return iterator(); }
iterator end() { return iterator(); }
};
#include <algorithm>
int main() {
Container c;
std::for_each(c.begin(), c.end(), func); // compile errors
return 0;
}
Errors:
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2672: '_Iter_cat': no matching overloaded function found
1> c:\program files\microsoft visual studio 14.0\vc\include\algorithm(31): note: see reference to function template instantiation 'void std::_Debug_range_ptr<_InIt,_Fn1>(_InIt,_InIt,_Pty &,std::_Dbfile_t,std::_Dbline_t)' being compiled
1> with
1> [
1> _InIt=Container::iterator,
1> _Fn1=Functor,
1> _Pty=Functor
1> ]
1> [...]: note: see reference to function template instantiation '_Fn1 std::for_each<Container::iterator,Functor>(_InIt,_InIt,_Fn1)' being compiled
1> with
1> [
1> _Fn1=Functor,
1> _InIt=Container::iterator
1> ]
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2893: Failed to specialize function template 'iterator_traits<_Iter>::iterator_category std::_Iter_cat(const _Iter &)'
1> c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): note: With the following template arguments:
1> c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): note: '_Iter=Container::iterator'
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2672: '_Debug_range_ptr2': no matching overloaded function found
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2780: 'void std::_Debug_range_ptr2(_RanIt,_RanIt,_Pty &,std::_Dbfile_t,std::_Dbline_t,std::random_access_iterator_tag)': expects 6 arguments - 5 provided
1> c:\program files\microsoft visual studio 14.0\vc\include\xutility(820): note: see declaration of 'std::_Debug_range_ptr2'
1>c:\program files\microsoft visual studio 14.0\vc\include\xutility(838): error C2780: 'void std::_Debug_range_ptr2(_InIt,_InIt,_Pty &,std::_Dbfile_t,std::_Dbline_t,std::input_iterator_tag)': expects 6 arguments - 5 provided
1> c:\program files\microsoft visual studio 14.0\vc\include\xutility(811): note: see declaration of 'std::_Debug_range_ptr2'
MSVC has more extensive debug checks when using iterators. Presumably this requires a more complete definition of the iterator with all its embedded types.
Traditionally iterators have been derived from std::iterator<> that provides default definitions for the embedded types required.
template<
class Category,
class T,
class Distance = std::ptrdiff_t,
class Pointer = T*,
class Reference = T&
> struct iterator;
A change to the code as follows should clear things up;
struct iterator : std::iterator<
std::input_iterator_tag, // or as required
int
>
Usually iterators are defined as derived classes of the standard class std::iterator that is declared like
template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&> struct iterator;
One of its template parameters is Category that determinates the category tag of the iterator such as for example std::input_iterator_tag.
In the debug mode the compiler performs some checks based on the category of the iterator.
You should follow this standard model of defining iterators.
Why can't I use an abstract class like an interface at runtime.
I get the output:
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(615): error C2259: 'Creature' : cannot instantiate abstract class
1> due to following members:
1> 'std::string Creature::Move(std::vector<std::string,std::allocator<_Ty>> &)' : is abstract
1> with
1> [
1> _Ty=std::string
1> ]
1> visual studio 2013\projects\cpp_demo\cpp_demo\creature.h(9) : see declaration of 'Creature::Move'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(614) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
1> with
1> [
1> _Ty=Creature
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(752) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled
1> with
1> [
1> _Ty=Creature
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(580) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=Creature
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(650) : see reference to class template instantiation 'std::is_empty<_Alloc>' being compiled
1> with
1> [
1> _Alloc=std::allocator<Creature>
1> ]
1> visual studio 2013\projects\cpp_demo\cpp_demo\main.cpp(7) : see reference to class template instantiation 'std::vector<Creature,std::allocator<_Ty>>' being compiled
1> with
1> [
1> _Ty=Creature
1> ]
My code:
int main()
{
unique_ptr<vector<Creature>> pCreatures(new vector<Creature>);
unique_ptr<Creature> pHuman(new Human());
pCreatures->push_back(*pHuman);
}
#include "stdafx.h"
#include "Creature.h"
class Human : public Creature
{
public:
virtual string Move(vector<string> &log);
};
#include "stdafx.h"
#include "IMove.h"
class Creature : public IMove
{
public:
virtual string Move(vector<string> &log) = 0;
virtual string GetState(vector<string> &log);
};
Please help.
You CAN use abstract class in vector or unique_ptr, e.g.
#include <vector>
#include <memory>
using namespace std;
class Interface {
public:
virtual ~Interface() = 0;
};
Interface::~Interface() {}
class Implementation : public Interface {
};
int main(int argc, char** argv) {
unique_ptr<Interface> p(new Implementation);
vector<unique_ptr<Interface>> v;
v.emplace_back(new Implementation);
vector<Interface> vi;
// This leads to compile error: vi.emplace_back();
}
Moreover, you CAN use vector<Interface> as long as you don't call any methods that potentially calls new Interface. For example, if you just declare a variable vector<Interface> v; it compiles, but if you push_back or emplace_back or resize, then it will have compile error because they will call new Interface.
The above code is tested under gcc-4.6.3.
You can use, but instead of using:
unique_ptr<vector<Creature>> pCreatures(new vector<Creature>);
use
vector<unique_ptr<Creature>> pCreatures;
so you will have a vectors of Creatures pointers, managed by unique_ptr.
There are, at least, two ways to use this vector:
Creating the objects directly into the vector:
pCreatures.emplace_back(new Human());
Moving an unique_ptr to it:
unique_ptr pHuman(new Human());
pCreatures.push_back(move(pHuman));
Below is a compact usage:
int main()
{
vector<unique_ptr<Creature>> pCreatures;
pCreatures.emplace_back(new Human());
unique_ptr<Creature> pHuman(new Human());
pCreatures.push_back(move(pHuman));
// example of usage
pCreatures[0]->Move();
}
Is the following code supposed to produce compilation error according to C++11 (if so why?) or is it a problem with VC11?
#include <vector>
#include <list>
#include <memory>
struct A
{
std::vector<std::unique_ptr<int>> v;
};
int main()
{
std::list<A> l;
l.sort([](const A& a1, const A& a2){ return true; });
}
Visual C++ 2012 produces the following compilation error:
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(606): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=int
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=int
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(751) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits(743) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector(655) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled
1> with
1> [
1> _Ty=std::allocator<std::unique_ptr<int>>
1> ]
1> d:\test2\test2.cpp(213) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
It's "a problem with VC", but only because you're misusing Visual Studio.
VC++ implements r-value references, but it does not implement compiler-generated move constructors/assignment operators. Which means that, if you want a type to be moveable, you must write one yourself.
A is not a moveable type, so the various std::list functions will attempt to copy them. And they'll fail when they try to copy a vector of unique_ptr. Hence the compiler error.
If you want move-aware objects in VC++, you must write move constructors/assignments for them yourself.
The problem is really in VC11, as it doesn't implement C++11 feature of automatically generating move operations (as already nailed by Nicol Bolas).
The following code compiles with VC10 SP1; in this code sample, move constructor is explicitly written (instead for move operator=, the copy-and-swap idiom is used).
#include <algorithm> // for std::swap (for copy-and-swap idiom)
#include <list>
#include <memory>
#include <vector>
struct A
{
std::vector<std::unique_ptr<int>> v;
A(A&& other)
: v( std::move(other.v) )
{
}
A& operator=(A other)
{
swap(*this, other);
return *this;
}
friend void swap(A& lhs, A& rhs)
{
using std::swap;
swap(lhs.v, rhs.v);
}
};
int main()
{
std::list<A> l;
l.sort( []( const A& , const A& ){ return true; } );
}
It was an issue with Visual C++ 2012 (acknowledged by Microsoft on Connect: Compile error in C++ code sorting a list of objects holding a vector of unique_ptr) and it was already fixed in Visual C++ 2013.
Also, I'd like to point out that an issue had nothing to do with the fact, that Visual C++ does not implicitly generate move constructors. If you explicitly delete all copy and move constructors in struct A (yes, it will make impossible inserting objects of type A into the list, but that is beside the point) in my original example the code still is not supposed to copy or move any objects and as such produce compilation errors:
#include <vector>
#include <list>
#include <memory>
struct A
{
std::vector<std::unique_ptr<int>> v;
A(A&&) = delete;
A(const A&) = delete;
};
int main()
{
std::list<A> l;
l.sort([](const A& a1, const A& a2){ return true; });
}
I am trying to create a map using two arrays. Here is the code:
#include <algorithm>
#include <iostream>
#include <map>
#include <utility>
#include <iterator>
#include <string>
using namespace std;
using std::transform;
int main(){
const char* word[]={"A","B","C","D","E"};
const char * clue[]={"a","b","c","d","e"};
map<string,string>dictionary;
map<string,string>::iterator it;
transform(word, word+sizeof(word)/sizeof(word[0]), clue,
inserter(dictionary,dictionary.end()), make_pair<string,string>);
for (it=dictionary.begin(),it!=dictionary.end();it++)
cout<<it->first<< " "<<it->second<<endl;
return 0;
}
But here are the mistakes:
1>------ Build started: Project: map_array, Configuration: Debug Win32 ------
1>Build started 8/21/2010 4:27:25 PM.
1>PrepareForBuild:
1> Creating directory "c:\users\david\documents\visual studio 2010\Projects\map_array\Debug\".
1>InitializeBuildStatus:
1> Creating "Debug\map_array.unsuccessfulbuild" because "AlwaysCreate" was specified.
1>ClCompile:
1> map_array.cpp
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(16): error C2784: '_OutTy *std::transform(_InIt1,_InIt1,_InTy (&)[_InSize],_OutTy (&)[_OutSize],_Fn2)' : could not deduce template argument for '_OutTy (&)[_OutSize]' from 'std::insert_iterator<_Container>'
1> with
1> [
1> _Container=std::map<std::string,std::string>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\algorithm(1293) : see declaration of 'std::transform'
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(16): error C2784: '_OutTy *std::transform(_InIt1,_InIt1,_InIt2,_OutTy (&)[_OutSize],_Fn2)' : could not deduce template argument for '_OutTy (&)[_OutSize]' from 'std::insert_iterator<_Container>'
1> with
1> [
1> _Container=std::map<std::string,std::string>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\algorithm(1279) : see declaration of 'std::transform'
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(16): error C2914: 'std::transform' : cannot deduce template argument as function argument is ambiguous
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(16): error C2784: '_OutIt std::transform(_InIt1,_InIt1,_InTy (&)[_InSize],_OutIt,_Fn2)' : could not deduce template argument for '_OutIt' from 'std::insert_iterator<_Container>'
1> with
1> [
1> _Container=std::map<std::string,std::string>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\algorithm(1267) : see declaration of 'std::transform'
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(16): error C2914: 'std::transform' : cannot deduce template argument as function argument is ambiguous
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(16): error C2784: '_OutIt std::transform(_InIt1,_InIt1,_InIt2,_OutIt,_Fn2)' : could not deduce template argument for '_OutIt' from 'std::insert_iterator<_Container>'
1> with
1> [
1> _Container=std::map<std::string,std::string>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\algorithm(1249) : see declaration of 'std::transform'
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(16): error C2780: '_OutTy *std::transform(_InIt,_InIt,_OutTy (&)[_OutSize],_Fn1)' : expects 4 arguments - 5 provided
1> c:\program files\microsoft visual studio 10.0\vc\include\algorithm(1127) : see declaration of 'std::transform'
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(16): error C2780: '_OutIt std::transform(_InIt,_InIt,_OutIt,_Fn1)' : expects 4 arguments - 5 provided
1> c:\program files\microsoft visual studio 10.0\vc\include\algorithm(1111) : see declaration of 'std::transform'
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(20): error C2143: syntax error : missing ';' before ')'
1>c:\users\david\documents\visual studio 2010\projects\map_array\map_array\map_array.cpp(20): error C2451: conditional expression of type 'std::_Tree_iterator<_Mytree>' is illegal
1> with
1> [
1> _Mytree=std::_Tree_val<std::_Tmap_traits<std::string,std::string,std::less<std::string>,std::allocator<std::pair<const std::string,std::string>>,false>>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.19
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
How do I fix this problem?
EDITED
I have tried another version of the solution to this problem (using by the Internet and C++ sites), and I have found a way to solve this problem like this
#include <algorithm>
#include <iostream>
#include <map>
#include <utility>
#include <iterator>
#include <string>
using namespace std;
template<typename KeyType, typename ValueType, int N>
class mapmaker
{
std::pair<KeyType, ValueType> (&table)[N];
const KeyType (&keys)[N];
const ValueType (&vals)[N];
template<int pos> void fill_pair()
{
table[pos].first = keys[pos];
table[pos].second = vals[pos];
fill_pair<pos-1>();
}
template<> void fill_pair<0>()
{
table[0].first = keys[0];
table[0].second = vals[0];
}
public:
mapmaker( std::pair<KeyType, ValueType> (&t)[N], const KeyType (&k)[N], const ValueType (&v)[N] )
: table(t), keys(k), vals(v)
{
fill_pair<N-1>();
}
};
template<typename KeyType, typename ValueType, int N>
std::map<KeyType,ValueType> make_map(const KeyType (&keys)[N], const ValueType (&vals)[N])
{
std::pair<KeyType, ValueType> table[N];
mapmaker<KeyType, ValueType, N>( table, keys, vals );
return std::map<KeyType, ValueType>(table, table+N);
}
int main(){
static const string word[]={"A","B","C","D","E"};
static const string clue[]={"a","b","c","d","e"};
static map<string,string>dictionary=make_map(word,clue);
map<string,string>::iterator it;
//transform(word,word+sizeof(word)/sizeof(word[0]),clue,clue,inserter(dictionary,dictionary.end()));
for (it=dictionary.begin();it!=dictionary.end();it++)
cout << it->first << " " << it->second << endl;
//cout<<dictionary.size();
return 0;
}
The code looks valid, and it compiles with GCC, after changing the syntax error in your for loop (the comma should be a semicolon after the initial part).
Note that C++03 compilers are not necessarily required to correctly get a function pointer with make_pair<string,string>. Only C++0x allows directly getting the address of a function template specialization without casting but merely giving a template argument list, but usually C++03 compilers backpart that feature and implement it even in C++03 mode. But i think it is unlikely that this is the source of your problem here.
Maybe can we make something simpler.
vector<string> aKeys = {"#1", "#2", "#3", "#4"};
vector<int> aValues = {1, 2, 3, 4};
map<string,int> createdDict = {};
for (auto i = 0; i < aKeys.size(); i++) {
createdDict[aKeys[i]] = aValues[i];
}