I have following code:
#include <iostream>
using namespace std;
template<class T>
T max(T *data,int len){
int i;
T Max=data[0];
for (int i=1;i<len;i++){
if (data[i]>max){
Max=data[i];
}
}
return Max;
}
int mai(){
int i[]={12,34,10,9,56,78,30};
int len=sizeof(i)/sizeof(i[0]);
cout<<max(i,len)<<"\n";
return 0;
}
But when I compile it, I get the following errors:
generic_max, Configuration: Debug Win32 ------
1>Build started 7/29/2010 1:03:25 AM.
1>InitializeBuildStatus:
1> Touching "Debug\generic_max.unsuccessfulbuild".
1>ClCompile:
1> generic_max.cpp
1>c:\users\david\documents\visual studio 2010\projects\generic_max\generic_max\generic_max.cpp(10): error C2563: mismatch in formal parameter list
1> c:\users\david\documents\visual studio 2010\projects\generic_max\generic_max\generic_max.cpp(22) : see reference to function template instantiation 'T max<int>(T *,int)' being compiled
1> with
1> [
1> T=int
1> ]
1>c:\users\david\documents\visual studio 2010\projects\generic_max\generic_max\generic_max.cpp(10): error C2568: '>' : unable to resolve function overload
1> c:\users\david\documents\visual studio 2010\projects\generic_max\generic_max\generic_max.cpp(4): could be 'T max(T *,int)'
1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(2086): or 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)'
1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(2078): or 'const _Ty &std::max(const _Ty &,const _Ty &)'
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.95
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Please help me to fix this problem.
C++ is case-sensitive.
#include <iostream>
// Note the omission of `using namespace std;`. The declaration can
// introduce clashes if one of your functions happen to have the same name
// as the functions in the std namespace.
template<class T>
T max(T *data,int len) {
//int i; <-- Not needed? The for loop already has an `i` declared in it.
T Max=data[0];
for (int i=1;i<len;i++) {
/****** Note `Max`, not `max` ******/
// The typo in your code snippet is what's causing the C2563.
// `max` (in this context) refers to the function
// `template<class T> T max(T *data,int len)` that has been declared.
// `Max` refers to the variable declared in this function.
// (For the sake of readability, variable names should not similar
// to the function name).
if (data[i]>Max) {
Max=data[i];
}
}
return Max;
}
/****** Note `main()`, not `mai()` ******/
int main() {
int i[]={12,34,10,9,56,78,30};
int len=sizeof(i)/sizeof(i[0]);
// `cout` should be just qualified with `std::` instead of
// `using namespace std`.
std::cout<<max(i,len)<<"\n";
return 0;
}
Your max function is conflicting with the standard C++ function std::max because you have written using namespace std at the top of your program, which brings everything in the std namespace into the default namespace. The compiler can't tell if you wanted to call your max or some version of std::max.
Either change the name of your function, or remove using namespace std and explicitly prefix things in your program in the std namespace with std::.
if (data[i]>max) - change max to Max
In line 10, you probably mean >Max and not >max.
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.
I have a 2D character array (I don't want to use array of std::string). How can I sort the strings (char*) in ascending order according to the length of the string using std::sort()?
I have tried the following. But it doesn't work.
char names[100][30];
bool comp(const char* a, const char* b){
return strlen(a)<strlen(b);
}
int main(){
...
//I want to sort the first n strings
sort(names,names+n,comp); //n<=100
...
}
I have found these errors:
1>e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3128) : error C2075: '_Val' : array initialization needs curly braces
1> e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3150) : see reference to function template instantiation 'void std::_Insertion_sort1<_BidIt,bool(__cdecl *)(const char *,const char *),char[30]>(_BidIt,_BidIt,_Pr,_Ty (*))' being compiled
1> with
1> [
1> _BidIt=char (*)[30],
1> _Pr=bool (__cdecl *)(const char *,const char *),
1> _Ty=char [30]
1> ]
1> e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3270) : see reference to function template instantiation 'void std::_Insertion_sort<_RanIt,bool(__cdecl *)(const char *,const char *)>(_BidIt,_BidIt,_Pr)' being compiled
1> with
1> [
1> _RanIt=char (*)[30],
1> _BidIt=char (*)[30],
1> _Pr=bool (__cdecl *)(const char *,const char *)
1> ]
1> e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3279) : see reference to function template instantiation 'void std::_Sort<char(*)[30],int,bool(__cdecl *)(const char *,const char *)>(_RanIt,_RanIt,_Diff,_Pr)' being compiled
1> with
1> [
1> _RanIt=char (*)[30],
1> _Diff=int,
1> _Pr=bool (__cdecl *)(const char *,const char *)
1> ]
1> e:\projects visual studio2008\sample\sample\sorting.cpp(51) : see reference to function template instantiation 'void std::sort<char(*)[30],bool(__cdecl *)(const char *,const char *)>(_RanIt,_RanIt,_Pr)' being compiled
1> with
1> [
1> _RanIt=char (*)[30],
1> _Pr=bool (__cdecl *)(const char *,const char *)
1> ]
1>e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3133) : error C2106: '=' : left operand must be l-value
1>e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3140) : error C2106: '=' : left operand must be l-value
1>e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3141) : error C2106: '=' : left operand must be l-value
1>Build log was saved at "file://e:\projects visual studio2008\sample\sample\Debug\BuildLog.htm"
1>sample - 4 error(s), 3 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
If your data is in
char names[100][30];
then you cannot sort "the pointers" because that data structure has no pointers at all... just 100*30 = 3000 characters one after another.
Therefore to do the sorting you will need to actually move around the 100 rows will all their content.
std::sort cannot be used directly because the data structure is an array of arrays, and arrays are in C++ second-class citizens (for example you cannot assign an array to another).
std::sort requires that its iterator type parameter must be:
ValueSwappable and RandomAccessIterator.
The type of dereferenced iterator type must meet the requirements of:
MoveAssignable and MoveConstructible.
Unfortunately, arrays are not swappable (i.e., you cannot assign one to the other). Consequently, you can't use std::sort with arrays.
What you can do is use std::array<std::array<char, N>, M> in the following manner:
template<std::size_t N, std::size_t M>
void custom_sort(std::array<std::array<char, M>, N> &arrs) {
std::sort(std::begin(arrs), std::end(arrs), [](auto const &a, auto const &b){ return strnlen(a.data(), M) < strnlen(b.data(), M); });
}
LIVE DEMO
Impovements to code thanks to #Jarod42
As already mentioned, arrays can't be assigned. Structures can be assigned, so this might be close to what you want. The array of structures might be padded for alignment. In the case of Visual Studio 2015, the array of structures was not padded, so the memory layout was the same as a 2d array.
update - changed to using references for compare parameters and switched to strnlen as suggested by Jarod42.
#include <algorithm>
#include <cstring>
using namespace std;
typedef struct
{
char name[30];
}name;
name names[4] = { { "12345678" },{ "123" },{ "12345" },{ "12" } };
bool comp(const name &a, const name &b)
{
return strnlen(a.name,30) < strnlen(b.name,30);
}
int main(){
sort(names, names+4, comp);
return 0;
}
You can try this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define M 10000
int main()
{
char names[M][15];
int n, i;
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%s", names[i]);
qsort(names, n, 15, (int (*)(const void *, const void *))strcmp);
for(i = 0; i < n; i++)
printf("%s\n", names[i]);
}
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];
}
I'm trying to use STL, but the following doesn't compile. main.cpp:
#include <set>
#include <algorithm>
using namespace std;
class Odp
{
public:
set<int> nums;
bool IsOdd(int i)
{
return i % 2 != 0;
}
bool fAnyOddNums()
{
set<int>::iterator iter = find_if(nums.begin(), nums.end(), &Odp::IsOdd);
return iter != nums.end();
}
};
int main()
{
Odp o;
o.nums.insert(0);
o.nums.insert(1);
o.nums.insert(2);
}
The error is:
error C2064: term does not evaluate to a function taking 1 arguments
1> c:\program files\microsoft visual studio 10.0\vc\include\algorithm(95) : see reference to function template instantiation '_InIt std::_Find_if<std::_Tree_unchecked_const_iterator<_Mytree>,_Pr>(_InIt,_InIt,_Pr)' being compiled
1> with
1> [
1> _InIt=std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>,
1> _Mytree=std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>,
1> _Pr=bool (__thiscall Odp::* )(int)
1> ]
1> main.cpp(20) : see reference to function template instantiation '_InIt std::find_if<std::_Tree_const_iterator<_Mytree>,bool(__thiscall Odp::* )(int)>(_InIt,_InIt,_Pr)' being compiled
1> with
1> [
1> _InIt=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>,
1> _Mytree=std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>,
1> _Pr=bool (__thiscall Odp::* )(int)
1> ]
What am I doing wrong?
It needs to be declared static:
static bool IsOdd(int i)
Otherwise, you'd be asking find_if to call an instance method without an instance.
The problem is you are passing a pointer to member function. To call that function you would also need a pointer to this but the find_if doesn't let you to pass it. A solution is to wrap it using a function object, see Boost Bind (http://www.boost.org/doc/libs/1_43_0/libs/bind/bind.html) and Boost Function (http://www.boost.org/doc/libs/1_37_0/doc/html/function.html).
IsOdd does not use the class's internals in any way, so don't make it a member function. Instead, pull it out as a standalone function. Then you can call find_if with &IsOdd.
However, there is a benefit to taking things a step further and defining it as a function object:
#include <functional>
struct IsOdd : public unary_function<int, bool>
{
bool operator()(int i) const { return i % 2 != 0; }
};
Then calling find_if with IsOdd() will inline the code within the find_if loop instead of dereferencing a function pointer and making a function call.