Creating an Array of pointers to member functions - c++

In short, I tried searching on how to do this, but I seem to be missing something. One constraint to my problem: Human.h cannot change. We must operate with what we've been given. I am also told to create the array of pointers to members to decide on which function needs to be called.
Here's what I have:
Human.h
class Human
{
private:
void meleeAttack(std::string const& target);
void rangedAttack(std::string const& target);
void intimidatingShout(std::string const& target);
public:
void action(std::string const& action_name, std::string const& target);
};
Human.cpp
#include "Human.h"
typedef void (Human::* Human_mem_fnPtr)(std::string target);
void Human::meleeAttack(std::string const& target)
{
std::cout << "Melee Attack performed on " << target << "!\n";
}
void Human::rangedAttack(std::string const& target)
{
std::cout << "Ranged Attack performed on " << target << "!\n";
}
void Human::intimidatingShout(std::string const& target)
{
std::cout << "Shout performed on " << target << "!\n";
}
void Human::action(std::string const& action_name, std::string const& target)
{
//error on initialization--expression must be an lvalue or function designation--but they ARE func designations...
Human_mem_fnPtr fnPtr[] = {&Human::meleeAttack(target), &Human::rangedAttack(target), &Human::intimidatingShout(target)};
}
From what I found online, I am going in the right direction here. What am I missing?

A couple of points:
Doing pointers to functions is made much easier with the std::function<> template class.
Using a old-style array is not really the best choice these days.
A map or unordered_map would be a much better option, with a definition like this:
using ActionMap = std::unordered_map<const std::string, std::function<void(const std::string&)>;
When adding your functions to this map you would use something like the following:
mActionMap["rangedAttack"] = std::mem_fn(&Human::rangedAttack);
This will give you a cleaner and easier to maintain option and should compile cleanly.
Note that the std::mem_fn is required to wrap a member function of a class.
Edit: Per your comment below, Id still suggest using as many of the modern C++ constructs as possible.
using ActionFunc = std::function<void(const std::string&)>;
And then:
ActionFunc actions[] = { std::mem_fn(&Human::rangedAttack), ...}
or:
std::array<ActionFunc> actions = ...

Related

Create a `map` using `unique_ptr`

I originally had a problem creating a map of classes, with some help
I realized I actually need a map<string, unique_ptr<myclass>>.
To be more precise:
I have a bunch of specialized classes with a common ancestor.
specialized classes are actually specialized from the same template.
I have a std::map<std::string, unique_ptr<ancestor>> taking ownership
of my instances (I hope).
I need ownership because the function creating the instances is in a
completely different section of code than the place using them.
If useful: I create the map at initialization time and then I only
reference it at runtime; for all practical purposes after initializing
it (a complex affair, involving reading config files) it could become
const.
A minimal example of what I need to achieve is:
#include <iostream>
#include <string>
#include <memory>
#include <map>
class generic {
std::string _name;
public:
generic(std::string name) : _name(name) {}
virtual ~generic() = default;
virtual std::string name() { return _name; }
virtual std::string value() { return "no value in generic"; }
};
template <class T> class special : public generic {
T _value;
public:
special(std::string name, T value) : generic(name), _value(value) {}
virtual ~special() = default;
std::string value() override { return std::to_string(_value); }
};
template <typename T> void add_item(std::map <std::string, std::unique_ptr<generic>> &m, const std::string &n, const T &v) {
m[n] = std::make_unique<special<T>>(typeid(v).name(), v);
}
int
main() {
std::map <std::string, std::unique_ptr<generic>> instances;
add_item<int>(instances, "int", 1);
add_item<bool>(instances, "bool", true);
add_item<float>(instances, "float", 3.1415);
for (auto i : instances) {
std::cout << i.first << " -- " << i.second.get()->name() << " -- " << i.second.get()->value() << std::endl;
}
return 0;
}
Unfortunately I seem to be missing something because compilation bombs with "error: use of deleted function".
Can someone be so kind to help me sort this out?
In this loop you try to copy unique_ptrs, but the unique_ptr copy constructor is deleted.
for (auto i : instances) {
You need to take them by reference instead:
for (auto& i : instances) {

Should you have a getter function for class array?

I'm learning C++, and have a question related to classes and templates.
I know it's good practice to have "getters" for every variable in your class and a "setter" function. But with the code shown below, should you have a "getter" function for the array? In theory, the print function would serve the same purpose as the "getter" function would - print out everything in the array. If it is required, what would the correct code be to return that array? The array is an array of class objects.
My thinking and the code thus far:
queue.h
#pragma once
template<class T>
class Queue {
public:
Queue(int = 1);
~Queue();
void setQueue(int);
void enqueue(T);
void dequeue();
const T* getQueueArray() const;
const int getArraySize() const;
const int getArrayIndex() const;
void printQueue();
private:
T* queueArray;
int arraySize, arrayIndex;
};
queue.cpp
#include <iostream>
#include "queue.h"
template<class T>
Queue<T>::Queue(int arraySize) {
this->setQueue(arraySize);
}
template<class T>
Queue<T>::~Queue() {
delete [] this->queueArray;
}
template<class T>
void Queue<T>::setQueue(int arraySize) {
this->arraySize = arraySize;
delete [] this->queueArray;
this->queueArray = new T[arraySize];
this->arrayIndex = 0;
}
template<class T>
void Queue<T>::enqueue(T object) {
if (this->arrayIndex == this->arraySize) {
std::cout << "Rinda ir pilna, nevar pievienot elementu!\n";
}
else {
this->queueArray[this->arrayIndex] = object;
this->arrayIndex++;
}
}
template<class T>
void Queue<T>::dequeue() {
if (this->arrayIndex == 0) {
std::cout << "Rinda ir tuksa!\n";
}
else {
for (int i = 0; i < this->arraySize - 1; i++) {
this->queueArray[i] = this->queueArray[i + 1];
}
this->arrayIndex--;
}
}
template<class T>
const T* Queue<T>::getQueueArray() const {
return this->queueArray;
}
template<class T>
const int Queue<T>::getArraySize() const {
return this->arraySize;
}
template<class T>
const int Queue<T>::getArrayIndex() const {
return this->arrayIndex;
}
template<class T>
void Queue<T>::printQueue() {
for (int i = 0; i < this->arrayIndex; i++) {
std::cout << i + 1 << ". ";
this->queueArray[i].printHuman();
}
}
The array getter function works and returns a memory address. Is that behavior correct?
And I'd like to ask another question, for class print functions, which would be the better of the 2:
std::cout << "something something" << classVariable;
or
std::cout << "something something" << getClassVariable();
One way is accessing the variables directly and the other is using the "getter" functions. Does it matter and does using functions like that impact performance in a noticable way?
This post is largely opinion-based, but I'm going to offer my perspective. You've received comments telling you a few things.
First, I'd encourage you to do things "the C++ way". Templates are done in the header, and it's really gross to "#include "queue.cpp". But I understand at least for an example that's maybe okay, as it lets you focus on other things than all the code to implement the entire template. Just don't do it in practice.
As for getters and setters -- I disagree with some of the comments you're getting. I absolutely would NOT put a setter on the internal structure, but if this is a serious class, I'd absolutely implement some way to inspect the full contents.
Imagine, after all, that someone wants to be able to count how many elements in the queue have fulfill a particular constraint. You don't want to try to anticipate evreything someone might want to do. But you can certainly put some means of inspecting the contents, either by being able to get the current queue (const) or via iterators. Iterators are harder to implement, but they fit a lot of other algorithms. See the entire contents of #include .
So:
Yes on some sort of access system (a getter / iterator)
No on a setter
In addition to this, I'm not sure why your sample code isn't willing to grow the list if necessary, but if it's not going to, it should somehow indicate to the caller that it failed to enqueue properly.
First of all for templated classes, having the declaration in a header file and having the definitions on a source file wont work. So try putting them in the same header file.
I know it's good practice to have "getters" for every variable in your class and a "setter" function
Yes that is true but not always. Getting the actual data pointer will help for example when copying data to a buffer. Setting is usually done by assignment operators,
Value& operator=(const Object& other) { ... } // Copy assign operator.
Value& operator=(Object&& other) { ... } // Move assign operator.
So I would advice not to have a setter in these type of objects.
And I'd like to ask another question, for class print functions, which would be the better of the 2:
std::cout << "something something" << classVariable; or std::cout << "something something" << getClassVariable();
This is opinion based and usually you print the content to the console by overloading the << operator,
template<class T>
ostream& operator<<(ostream& os, const Queue<T>& dt)
{
os << /* print content */;
return os;
}
int main()
{
Queue<int> queue;
std::cout << "Printing queue! " << queue;
}
One way is accessing the variables directly and the other is using the "getter" functions. Does it matter and does using functions like that impact performance in a noticable way
Nope they wont. If you inline the functions, there wont be no performance differences. And make sure you enable optimizations or else additional debug information would slow it down. I would argue that using a getter function would be safer.

Templating on Enum Value to Select Handle Open/Close

I am writing a C++ wrapper for a C library that works with handles represented by integers. There are a bunch of open functions (Aopen, Bopen, Copen, Dopen, Eopen, ...) and corresponding close functions (Aclose, Bclose, Cclose, Dclose, Eclose, ...). I currently have wrapper classes implementing basic RAII, but I have a bit of code duplication, as each of these wrappers differs only in which open and close routine it calls. To get rid of this duplication I was thinking of templating on an enum I define with values for each of the routines (e.g. Atype, Bytpe, etc), and then selecting the correct open and close function at compile time. It would like something like:
TypeWrapper<AType> wrapped_a(...)
TypeWrapper<BType> wrapped_b(...)
...
Is this a reasonable approach, is there a simpler approach, or is there a name for this type of construction?
Thank you!
You may do something like the following:
template <typename H, H Open(const char*), void Close(H)>
class Wrapper
{
public:
Wrapper(const char* file) : h(Open(file)) {}
~Wrapper() { Close(h); }
Wrapper(const Wrapper&) = delete;
Wrapper& operator = (const Wrapper&) = delete;
private:
H h;
};
And then using Wrapper_A = Wrapper<AHandle, AOpen, AClose>;
Live example
What you're looking for is Template Specialization.
Basically, this is done by templating your TypeWrapper class on an enum value, then providing specialized implementations for the open/close calls for each enum value.
An example is worth a thousand words: live example
#include <iostream>
using namespace std;
enum Type {
AType = 0,
BType,
CType,
};
void AOpen() { std::cout << "A open." << std::endl; }
void BOpen() { std::cout << "B open." << std::endl; }
void COpen() { std::cout << "C open." << std::endl; }
template<Type T>
class TypeWrapper {
public:
void open();
void close();
};
template<>
void TypeWrapper<AType>::open() { AOpen(); }
template<>
void TypeWrapper<BType>::open() { BOpen(); }
template<>
void TypeWrapper<CType>::open() { COpen(); }
int main() {
TypeWrapper<AType> wrapped_a;
TypeWrapper<BType> wrapped_b;
wrapped_a.open();
wrapped_b.open();
return 0;
}

Map with multiple keys in C++

I want to store data by both, their name and their index. In other words, I want to map string names to objects and also give them a custom order.
What I came up with first is a std::vector of pairs of the string key and the object. The order was given by the position in the vector.
std::vector<std::pair<std::string, object> >
But this approach seems to be suboptimal since it doesn't automatically check for the uniqueness of string names. Moreover it feels wrong to group the objects by their order first, because logically their first order distinction is the name.
I need a data structure that allows access by both name and index.
std::magic<std::string, unsigned int, object> collection;
// access by either string or unsigned int key
collection.insert("name", 42, new object());
collection["name"]
collection[42]
Is there a data structure for this use case already? If not, how can I put one together, preferably using the standard library? Also I would like a way to insert new elements at the position after a given element without moving all further elements around.
Boost provides a set of containers just for this purpose, see: boost::multiindex
I'm trying to write a solution using std library, as requested in the original post. I will not have access to boost in my resource-constrained system. I've drafted a two-map system mentioned in the comments.
A big downside is that you'll have to wrap each public function that a std::map or std::vector normally offers, and my wrapper might not be as optimal.
But, this is a start. Let me know of improvements to my answer in the comment, and I'll edit the response when I can
#include <unordered_map>
#include <string>
#include <iostream>
struct Object
{
int val;
};
template <typename T>
class MultiKeyMap
{
std::unordered_map<std::string, uint> nameToIdMap;
std::unordered_map<uint, T> idToValMap;
public:
T& find(const std::string& name)
{
return find(nameToIdMap[name]);
}
T& find(const uint id)
{
return idToValMap[id];
}
T& operator[](const std::string& name) { return find(name); }
T& operator[](const uint id) { return find(id); }
void insert(uint id, const std::string& name, T&& val)
{
nameToIdMap[name] = id;
idToValMap[id] = val;
}
};
int main()
{
MultiKeyMap<Object> mkmap;
mkmap.insert(1, "one", Object{11});
mkmap.insert(2, "two", Object{22});
std::cout << "key=1: val=" << mkmap[1].val << "\n";
std::cout << "key='one': val=" << mkmap["one"].val << "\n";
std::cout << "key=2: val=" << mkmap[2].val << "\n";
std::cout << "key='two': val=" << mkmap["two"].val << "\n";
}

Extension methods in c++

I was searching for an implementation of extension methods in c++ and came upon this comp.std.c++ discussion which mentions that polymorphic_map can be used to associated methods with a class, but, the provided link seems to be dead. Does anyone know what that answer was referring to, or if there is another way to extend classes in a similar manner to extension methods (perhaps through some usage of mixins?).
I know the canonical C++ solution is to use free functions; this is more out of curiosity than anything else.
Different languages approach development in different ways. In particular C# and Java have a strong point of view with respect to OO that leads to everything is an object mindset (C# is a little more lax here). In that approach, extension methods provide a simple way of extending an existing object or interface to add new features.
There are no extension methods in C++, nor are they needed. When developing C++, forget the everything is an object paradigm --which, by the way, is false even in Java/C# [*]. A different mindset is taken in C++, there are objects, and the objects have operations that are inherently part of the object, but there are also other operations that form part of the interface and need not be part of the class. A must read by Herb Sutter is What's In a Class?, where the author defends (and I agree) that you can easily extend any given class with simple free functions.
As a particular simple example, the standard templated class basic_ostream has a few member methods to dump the contents of some primitive types, and then it is enhanced with (also templated) free functions that extend that functionality to other types by using the existing public interface. For example, std::cout << 1; is implemented as a member function, while std::cout << "Hi"; is a free function implemented in terms of other more basic members.
Extensibility in C++ is achieved by means of free functions, not by ways of adding new methods to existing objects.
[*] Everything is not an object.
In a given domain will contain a set of actual objects that can be modeled and operations that can be applied to them, in some cases those operations will be part of the object, but in some other cases they will not. In particular you will find utility classes in the languages that claim that everything is an object and those utility classes are nothing but a layer trying to hide the fact that those methods don't belong to any particular object.
Even some operations that are implemented as member functions are not really operations on the object. Consider addition for a Complex number class, how is sum (or +) more of an operation on the first argument than the second? Why a.sum(b); or b.sum(a), should it not be sum( a, b )?
Forcing the operations to be member methods actually produces weird effects --but we are just used to them: a.equals(b); and b.equals(a); might have completely different results even if the implementation of equals is fully symmetric. (Consider what happens when either a or b is a null pointer)
Boost Range Library's approach use operator|().
r | filtered(p);
I can write trim for string as follows in the same way, too.
#include <string>
namespace string_extension {
struct trim_t {
std::string operator()(const std::string& s) const
{
...
return s;
}
};
const trim_t trim = {};
std::string operator|(const std::string& s, trim_t f)
{
return f(s);
}
} // namespace string_extension
int main()
{
const std::string s = " abc ";
const std::string result = s | string_extension::trim;
}
This is the closest thing that I have ever seen to extension methods in C++. Personally i like the way it can be used, and possibly this it the closest we can get to extension methods in this language. But there are some disadvantages:
It may be complicated to implement
Operator precedence may be not that nice some times, this may cause surprises
A solution:
#include <iostream>
using namespace std;
class regular_class {
public:
void simple_method(void) const {
cout << "simple_method called." << endl;
}
};
class ext_method {
private:
// arguments of the extension method
int x_;
public:
// arguments get initialized here
ext_method(int x) : x_(x) {
}
// just a dummy overload to return a reference to itself
ext_method& operator-(void) {
return *this;
}
// extension method body is implemented here. The return type of this op. overload
// should be the return type of the extension method
friend const regular_class& operator<(const regular_class& obj, const ext_method& mthd) {
cout << "Extension method called with: " << mthd.x_ << " on " << &obj << endl;
return obj;
}
};
int main()
{
regular_class obj;
cout << "regular_class object at: " << &obj << endl;
obj.simple_method();
obj<-ext_method(3)<-ext_method(8);
return 0;
}
This is not my personal invention, recently a friend of mine mailed it to me, he said he got it from a university mailing list.
The short answer is that you cannot do that. The long answer is that you can simulate it, but be aware that you'll have to create a lot of code as workaround (actually, I don't think there is an elegant solution).
In the discussion, a very complex workaround is provided using operator- (which is a bad idea, in my opinion). I guess that the solution provided in the dead link was more o less similar (since it was based on operator|).
This is based in the capability of being able to do more or less the same thing as an extension method with operators. For example, if you want to overload the ostream's operator<< for your new class Foo, you could do:
class Foo {
friend ostream &operator<<(ostream &o, const Foo &foo);
// more things...
};
ostream &operator<<(ostream &o, const Foo &foo)
{
// write foo's info to o
}
As I said, this is the only similar mechanism availabe in C++ for extension methods. If you can naturally translate your function to an overloaded operator, then it is fine. The only other possibility is to artificially overload an operator that has nothing to do with your objective, but this is going to make you write very confusing code.
The most similar approach I can think of would mean to create an extension class and create your new methods there. Unfortunately, this means that you'll need to "adapt" your objects:
class stringext {
public:
stringext(std::string &s) : str( &s )
{}
string trim()
{ ...; return *str; }
private:
string * str;
};
And then, when you want to do that things:
void fie(string &str)
{
// ...
cout << stringext( str ).trim() << endl;
}
As said, this is not perfect, and I don't think that kind of perfect solution exists.
Sorry.
To elaborate more on #Akira answer, operator| can be used to extend existing classes with functions that take parameters too. Here an example that I'm using to extend Xerces XML library with find functionalities that can be easily concatenated:
#pragma once
#include <string>
#include <stdexcept>
#include <xercesc/dom/DOMElement.hpp>
#define _U16C // macro that converts string to char16_t array
XERCES_CPP_NAMESPACE_BEGIN
struct FindFirst
{
FindFirst(const std::string& name);
DOMElement * operator()(const DOMElement &el) const;
DOMElement * operator()(const DOMElement *el) const;
private:
std::string m_name;
};
struct FindFirstExisting
{
FindFirstExisting(const std::string& name);
DOMElement & operator()(const DOMElement &el) const;
private:
std::string m_name;
};
inline DOMElement & operator|(const DOMElement &el, const FindFirstExisting &f)
{
return f(el);
}
inline DOMElement * operator|(const DOMElement &el, const FindFirst &f)
{
return f(el);
}
inline DOMElement * operator|(const DOMElement *el, const FindFirst &f)
{
return f(el);
}
inline FindFirst::FindFirst(const std::string & name)
: m_name(name)
{
}
inline DOMElement * FindFirst::operator()(const DOMElement &el) const
{
auto list = el.getElementsByTagName(_U16C(m_name));
if (list->getLength() == 0)
return nullptr;
return static_cast<DOMElement *>(list->item(0));
}
inline DOMElement * FindFirst::operator()(const DOMElement *el) const
{
if (el == nullptr)
return nullptr;
auto list = el->getElementsByTagName(_U16C(m_name));
if (list->getLength() == 0)
return nullptr;
return static_cast<DOMElement *>(list->item(0));
}
inline FindFirstExisting::FindFirstExisting(const std::string & name)
: m_name(name)
{
}
inline DOMElement & FindFirstExisting::operator()(const DOMElement & el) const
{
auto list = el.getElementsByTagName(_U16C(m_name));
if (list->getLength() == 0)
throw runtime_error(string("Missing element with name ") + m_name);
return static_cast<DOMElement &>(*list->item(0));
}
XERCES_CPP_NAMESPACE_END
It can be used this way:
auto packetRate = *elementRoot | FindFirst("Header") | FindFirst("PacketRate");
auto &decrypted = *elementRoot | FindFirstExisting("Header") | FindFirstExisting("Decrypted");
You can enable kinda extension methods for your own class/struct or for some specific type in some scope. See rough solution below.
class Extensible
{
public:
template<class TRes, class T, class... Args>
std::function<TRes(Args...)> operator|
(std::function<TRes(T&, Args...)>& extension)
{
return [this, &extension](Args... args) -> TRes
{
return extension(*static_cast<T*>(this), std::forward<Args>(args)...);
};
}
};
Then inherit your class from this and use like
class SomeExtensible : public Extensible { /*...*/ };
std::function<int(SomeExtensible&, int)> fn;
SomeExtensible se;
int i = (se | fn)(4);
Or you can declare this operator in cpp file or namespace.
//for std::string, for example
template<class TRes, class... Args>
std::function<TRes(Args...)> operator|
(std::string& s, std::function<TRes(std::string&, Args...)>& extension)
{
return [&s, &extension](Args... args) -> TRes
{
return extension(s, std::forward<Args>(args)...);
};
}
std::string s = "newStr";
std::function<std::string(std::string&)> init = [](std::string& s) {
return s = "initialized";
};
(s | init)();
Or even wrap it in macro (I know, it's generally bad idea, nevertheless you can):
#define ENABLE_EXTENSIONS_FOR(x) \
template<class TRes, class... Args> \
std::function<TRes(Args...)> operator| (x s, std::function<TRes(x, Args...)>& extension) \
{ \
return [&s, &extension](Args... args) -> TRes \
{ \
return extension(s, std::forward<Args>(args)...); \
}; \
}
ENABLE_EXTENSIONS_FOR(std::vector<int>&);
This syntactic sugar isn't available in C++, but you can define your own namespace and write pure static classes, using const references as the first parameter.
For example, I was struggling using the STL implementation for some array operations, and I didn't like the syntaxis, I was used to JavaScript's functional way of how array methods worked.
So, I made my own namespace wh with the class vector in it, since that's the class I was expecting to use these methods, and this is the result:
//#ifndef __WH_HPP
//#define __WH_HPP
#include <vector>
#include <functional>
#include <algorithm>
namespace wh{
template<typename T>
class vector{
public:
static T reduce(const std::vector<T> &array, const T &accumulatorInitiator, const std::function<T(T,T)> &functor){
T accumulator = accumulatorInitiator;
for(auto &element: array) accumulator = functor(element, accumulator);
return accumulator;
}
static T reduce(const std::vector<T> &array, const T &accumulatorInitiator){
return wh::vector<T>::reduce(array, accumulatorInitiator, [](T element, T acc){return element + acc;});
}
static std::vector<T> map(const std::vector<T> &array, const std::function<T(T)> &functor){
std::vector<T> ret;
transform(array.begin(), array.end(), std::back_inserter(ret), functor);
return ret;
}
static std::vector<T> filter(const std::vector<T> &array, const std::function<bool(T)> &functor){
std::vector<T> ret;
copy_if(array.begin(), array.end(), std::back_inserter(ret), functor);
return ret;
}
static bool all(const std::vector<T> &array, const std::function<bool(T)> &functor){
return all_of(array.begin(), array.end(), functor);
}
static bool any(const std::vector<T> &array, const std::function<bool(T)> &functor){
return any_of(array.begin(), array.end(), functor);
}
};
}
//#undef __WH_HPP
I wouldn't inherit nor compose a class with it, since I've never been able to do it peacefully without any side-effects, but I came up with this, just const references.
The problem of course, is the extremely verbose code you have to make in order to use these static methods:
int main()
{
vector<int> numbers = {1,2,3,4,5,6};
numbers = wh::vector<int>::filter(numbers, [](int number){return number < 3;});
numbers = wh::vector<int>::map(numbers,[](int number){return number + 3;});
for(const auto& number: numbers) cout << number << endl;
return 0;
}
If only there was syntactic sugar that could make my static methods have some kind of more common syntax like:
myvector.map([](int number){return number+2;}); //...