Nested template list error - c++

In header:
list< SKPair<VALUETYPE> > *values[256];
In implementation:
const list< SKPair<VALUETYPE> > *bucket = values[0];
typename list< SKPair<VALUETYPE> >::iterator it = bucket.begin();
The gcc compiler complains about the second line:
error: request for member ‘begin’ in ‘bucket’, which is of non-class type ‘const std::list<SKPair<int>, std::allocator<SKPair<int> > >*’
(Here in main I create a test instance of my class where VALUETYPE is int.) Any idea what I'm doing wrong?

Write:
typename list< SKPair<VALUETYPE> >::iterator it = bucket->begin();
The -> is needed here.

bucket is declared as a pointer, so you need a dereferencing operator to access its members:
auto it = bucket->begin();
Should do the trick if you have C++11's auto available.

Related

How do I declare an iterator for a map with the following template - std::map<std::string, T> my_map?

I have the following class declaration -
template <typename T>
class Polynomial{
std::map<std::string, T> _polynomial_
}
In a member function I declared an iterator for this -
typename std::map<std::string, T>::iterator it= _polynomial_.begin();
The completed member function looks like this -
template <typename T>
void Polynomial<T>::print(std::ostream& out) const
{
typename std::map<std::string, T>::iterator it= _polynomial_.begin();
std::string term;
while(it != _polynomial_.end()){
term = it->second;
term += it->first;
if(it->first < (T)0){
out << "-" << term;
}
else{
out << "+" << term;
}
term = "";
it++;
}
}
In main, I call the function as follows -
Polynomial <double> p1;
p1.add_term("x0",9.862);
std::cout << p1;
However this does not seem to work and I get errors. GCC complains of a
conversion error -
Polynomial.hpp:32:47: error: conversion from \u2018std::map, double, std::less >, std::allocator, double> > >::const_iterator {aka std::_Rb_tree_const_iterator, double> >}\u2019 to non-scalar type \u2018std::map, double, std::less >, std::allocator, double> > >::iterator {aka std::_Rb_tree_iterator, double> >}\u2019 requested
typename std::map::iterator it= polynomial.begin();
Can someone tell me what is the correct declaration of the iterator?
Polynomial<T>::print is a const member function, inside which the data member _polynomial_ becomes const too, that means what _polynomial_.begin() returns is a const_iterator, which can't be converted to iterator implicitly. (Note that std::map::begin is overloaded with const version and non-const version, the former returns const_iterator and the latter returns iterator.)
Change the code to
typename std::map<std::string, T>::const_iterator it = _polynomial_.begin();
// ^^^^^^
or use auto instead, it would deduce the correct type for you.
auto it = _polynomial_.begin();

Nested unordered_map has no member named ‘emplace’

I trying to fix pretty hard program to me I got from gamedev book. I think it's crashed because an author used Windows and I use Linux (g++). In short I have couple of classes to perform Application State's logic, and I have map of maps to hold states with its callbacks:
enum class StateType {
Intro = 1, MainMenu, Game, Paused, GameOver, Credits
};
using Bindings = std::unordered_map<std::string, Binding*>;
using CallbackContainer = std::unordered_map<std::string, std::function<void(EventDetails*)>>;
using Callbacks = std::unordered_map<StateType, CallbackContainer>;
class EventManager {
public:
...
template<class T>
bool AddCallback(StateType l_state, const std::string& l_name,
void(T::*l_func)(EventDetails*), T* l_instance) {
auto itr = m_callbacks.emplace(l_state, CallbackContainer()).first;
auto temp = std::bind(l_func, l_instance, std::placeholders::_1);
return itr->second.emplace(l_name, temp).second;
}
private:
Callbacks m_callbacks;
I'm not sure what parts of my code to include here. Anyway I get a terrible stack trace:
/usr/include/c++/5/bits/hashtable_policy.h: In instantiation of ‘struct std::__detail::__is_noexcept_hash<StateType, std::hash<StateType> >’:
/usr/include/c++/5/type_traits:137:12: required from ‘struct std::__and_<std::__is_fast_hash<std::hash<StateType> >, std::__detail::__is_noexcept_hash<StateType, std::hash<StateType> > >’
/usr/include/c++/5/type_traits:148:38: required from ‘struct std::__not_<std::__and_<std::__is_fast_hash<std::hash<StateType> >, std::__detail::__is_noexcept_hash<StateType, std::hash<StateType> > > >’
/usr/include/c++/5/bits/unordered_map.h:100:66: required from ‘class std::unordered_map<StateType, std::function<BaseState*()> >’
/home/xxx/Projects/mushrooom/BaseState.h:48:28: required from here
/usr/include/c++/5/bits/hashtable_policy.h:85:34: error: no match for call to ‘(const std::hash<StateType>) (const StateType&)’
noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
...
/usr/include/c++/5/bits/unordered_map.h:649:7: error: ‘value’ is not a member of ‘std::__not_<std::__and_<std::__is_fast_hash<std::hash<StateType> >, std::__detail::__is_noexcept_hash<StateType, std::hash<StateType> > > >’
equal_range(const key_type& __x) const
...
/home/xxx/Projects/mushrooom/EventManager.h: In member function ‘bool EventManager::AddCallback(StateType, const string&, void (T::*)(EventDetails*), T*)’:
/home/xxx/Projects/mushrooom/EventManager.h:93:32: error: ‘using Callbacks = class std::unordered_map<StateType, std::unordered_map<std::basic_string<char>, std::function<void(EventDetails*)> > > {aka class std::unordered_map<StateType, std::unordered_map<std::basic_string<char>, std::function<void(EventDetails*)> > >}’ has no member named ‘emplace’
auto itr = m_callbacks.emplace(l_state, CallbackContainer()).first;
Seems like Callbacks has no member emplace, but it's std::unordered_map and it has such method.
g++-5, linux
It has nothing to do with emplace - it is the missing hash function!
You are using an std::unordered_map, which is in other words a hash map. If you want to use an object as a key, this object must provide a function by which a hash value can be calculated.
You now have two options:
provide a template specialisation of std::hash for your class or pass an own class as third (hasher) template parameter to std::unordered_map
use std::map instead - this is a tree-map not requiring a hash function.

recursive variant container compiler error

I'd like a variant contain copies of objects of its type. Somehow it is not working:
struct value
{
};
class json;
using json = ::boost::variant<
::std::vector<::std::unique_ptr<json> >,
::std::unordered_map<::std::string, ::std::unique_ptr<json> >,
value
>;
json.hpp:116:2: error: conflicting declaration 'using json = '
>;
^
json.hpp:110:7: error: 'class json' has a previous declaration as 'class json'
class json;
I know of 2 workarounds already: ::std::unique_ptr<void>, with a custom deleter, as well as the possibility of using ::boost::any instead of the variant, but are these the only ways? The problem with ::boost::any is that I need to enable RTTI for it to work.
What about:
struct json : ::boost::variant<
::std::vector<::std::unique_ptr<json> >,
::std::unordered_map<::std::string, ::std::unique_ptr<json> >,
value
>
{
using variant::variant;
template <typename U>
json& operator=(U&& u)
{
variant::operator=(::std::forward<U>(u));
return *this;
}
};
That would be the solution, except it doesn't work for me with g++ (constructing json out of vector fails because of ambiguous constructor call). Construction from a const reference to such a vector works, but not not from a non-const reference. I have no idea why. In addition, unique_ptr doesn't work with boost::variant for me because it's uncopyable (shared_ptr does work).

boost bimap set_of with user defined comparator

I plan to use my own compare function with boost bimap. The issue i am trying to address is when i use boost bimap with a pointer, the comparison should not compare the two pointers but should compare the class which is pointed by the pointer.
I tried the following code. But it doesn't even compile. What am i doing wrong? Also is there a simpler way to achieve less function that compares two objects and not two pointers pointers)
typedef std::set<int> ruleset;
template <class myclass>
bool comp_pointer(const myclass &lhs, const myclass &rhs)
{
return ((*lhs) < (*rhs));
}
typedef boost::bimap<set_of<ruleset *, comp_pointer<ruleset *> >, int> megarulebimap;
Error messages:
party1.cpp:104:64: error: type/value mismatch at argument 2 in template parameter list for 'template struct boost::bimaps::set_of'
party1.cpp:104:64: error: expected a type, got 'comp_pointer'
party1.cpp:104:70: error: template argument 1 is invalid
party1.cpp:104:85: error: invalid type in declaration before ';' token
typedef std::set<int> ruleset;
struct ruleset_cmp {
bool operator()(const ruleset *lhs, const ruleset *rhs) const
{
return ((*lhs) < (*rhs));
}
};
typedef boost::bimap<set_of<ruleset *, ruleset_cmp>, int> megarulebimap;
Okay. The above snippet works. It appears a functor needs to be used here.

c++ template syntax error

My C++ is a little rusty having worked in Java and C# for the last half dozen years. I've got a stupid little error that I just cannot figure out.
I've pared the code down as much as possible.
#include <list>
template<class T> class Subscriber
{
virtual void published( T t ) = 0;
};
template <class T> class PubSub
{
private:
std::list< Subscriber<T>* > subscribers;
public:
void publish( T t );
};
template<class T> void PubSub<T>::publish( T t )
{
for( std::list< Subscriber<T>* >::iterator i = subscribers.begin(); i != subscribers.end(); ++i )
i->published( t );
}
When I try and compile this (by including this header file in a code file), I get the following error:
../util/pubsub.h: In member function ‘void PubSub<T>::publish(T)’:
../util/pubsub.h:18: error: expected `;' before ‘i’
../util/pubsub.h:18: error: ‘i’ was not declared in this scope
What am I missing here?
for( typename std::list< Subscriber<T>* >::iterator i = ...
^^^^^^^^
for( typename std::list< Subscriber<T>* >::iterator i = subscribers.begin(); i != subscribers.end(); ++i )
You need the typename because iterator is a dependent name. The compiler has to check the template type T before it knows whether iterator is a type or a value. In those cases, it assumes it to be a value, unless you add typename.
This
std::list< Subscriber<T>* >::iterator
needs to be this
typename std::list< Subscriber<T>* >::iterator
The compiler assumes nested names in templates are static variables (not types) until told otherwise.