Related
As we know in c++, we can reinitialize an array arr of size N with a value 0 as,
fill (arr, arr + N, 0);
But I need to reinitialize the array with a struct S,
struct S {
int b[2];
}
The actual code is,
#include <iostream>
using namespace std;
struct Dog
{
int count[2];
};
int main(){
...
Dog dogs[N];
...
while (T--)
{
...
for (int i = 0; i < M; ++i)
{
fill(dogs, dogs+N, {0});
...
}
...
}
}
For the case:
struct Dog { int count[2]; };
Dog dogs[N];
you can use:
std::fill(dogs, dogs+N, Dog{});
The third argument to fill must have the right type already, the compiler does not deduce the type from the iterator. So you cannot just use {} or {0}.
Consider using std::begin(dogs), std::end(dogs) instead of dogs, dog+N as that removes the possibility of using the wrong value for N.
I'm not sure why fill was designed this way, as it is certainly possible to write a function which does accept initializer list as well as normal values:
#include <algorithm>
template<typename It>
void mfill(It begin, It end, typename std::remove_reference<decltype(*begin)>::type const &v)
{
std::fill(begin, end, v);
}
struct Dog { int count[2]; };
int main()
{
Dog dogs[5];
mfill(dogs, dogs+5, {});
}
You can use fill_n as follows:
struct Dog
{
int count[2];
};
int main(){
Dog dogs[4] = {};
dogs[0].count[0] = 1;
std::fill_n(dogs, 0, Dog{});
}
Since Dog is a pod structure, you can default construct it in the last parameter of fill_n
Not to sure how to name this question because the problem itself is looking for a construct of which I don´t know its name.
The problem is I am dealing with programs whose control flow depends greatly of data.
For example I created a MIPS simulator which implemented a list of more than 50 instructions, each implemented on its own and everything governed by a huge switch case
switch (function){ //Function is an int, each function (eg SLL) is
case 0: //associated with one
if (state->debug_level > 0){
fprintf(state->debug_out, "SLL\n");
}
step_err = SLL(state, rs, rt, rd, sa);
break;
case 2:
if (state->debug_level > 0){
fprintf(state->debug_out, "SRL\n");
}
step_err = SRL(state, rs, rt, rd, sa);
break;
case 3:
if (state->debug_level > 0){
fprintf(state->debug_out, "SRA\n");
}
//
I have been told that this could have been implemented using function pointers, but to do so what I am looking for is a way of relating data of any kind, say a string to other data, say an integer. I am aware of maps but wouldn't want to push back each pair. I am looking for some sort of array like syntax I think if seen before which might look something similar to this:
¿type? function_codes[]{
0, "SLL";
2, "SRL";
3, "SRA";
...
}
I am not looking for a solution to this problem but a generic approach to introducing quick relationships between data and using this to modify control flow.
EDIT AFTER ANSWERS
What I was actually looking for but I didnt know was indeed maps but in particular its initialization syntax similar to an array (see accepted answer). This used with function pointers did the required job.
As you guessed, function pointers are in fact a good way to do this. Since you specify that you don't want to use a Map, this is how you would implement your integer-based function dispatch using an array of function pointers. Note that since I don't know the type signature of your MIPS functions (SLL, SRL, etc.) I've used dummy placeholder type names.
typedef ret_t (*mips_func)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t);
mips_func function_codes[] = {
&SLL,
&SRL,
&SRA,
...
};
//...Later, in the part of your code that used to contain the big switch statement
step_err = (*function_codes[function])(state, rs, rt, rd, sa);
The syntax &SLL gets a pointer to the function SLL, which I assume is already in scope because you can call it directly from your switch statement.
Note that this assumes the numeric codes for the functions are a continuous sequence of integers from 0 to [max code value]. If some numeric codes are unused, then you will either need to leave explicit gaps in your array (by placing a NULL pointer in one or more entries) or use std::map<int, mips_func> so that you can use arbitrary non-continuous integer values as keys to functions. Fortunately, using a Map still doesn't require push_backing each element, since C++ now has initializer lists. The same code using a Map would look like this:
typedef ret_t (*mips_func)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t);
std::map<int, mips_func> function_codes = {
{0, &SLL},
{2, &SRL},
{4, &SRA},
...
};
//Using the Map looks exactly the same, due to its overloaded operator[]
step_err = (*function_codes[function])(state, rs, rt, rd, sa);
For simplify you can use associative containers. If the order is important then use std::map, or std::unordered_map in the other case.
And you can use syntax similar to the desired
std::map<size_t, std::string> codes_map = decltype(codes_map) {
{ 0, "val1" },
{ 1, "val2" }
};
You could group the data as static members w/ the same name across structs, then use templates to access them generically:
struct A { auto call() const { return "((1))"; }; static const char * name; };
struct B { auto call() const { return "{{2}}"; }; static const char * name; };
struct C { auto call() const { return "<<3>>"; }; static const char * name; };
// n.b. these `T...` have: `sizeof(T) == ... == sizeof(empty_struct)`
const char * A::name = "A";
const char * B::name = "B";
const char * C::name = "C";
boost::variant (and the soon to be implemented std::variant) implements a type-safe union, which provides a very clean and efficient way of using these structs as values:
#include <cstdio>
#include <vector>
#include <boost/variant.hpp>
int main()
{
std::vector<boost::variant<A, B, C>> letters{A{}, B{}, C{}, B{}, A{}};
auto visitor = [](auto x) { std::printf("%s(): %s\n", x.name, x.call()); };
for (auto var : letters) { boost::apply_visitor(visitor, var); }
}
Demo
It seems like you have two problems: the flow-control issue (dispatch) and the map issue (an implementation note). I get that the program flow is nonstatic and unknowable at compile-time… but so is the map static? For static maps I get a lot of mileage out of using a traits-ish approach to create a compile-time mapping. Here’s a quick example mapping file suffixes to Objective-C enum constants:
namespace objc {
namespace image {
template <std::size_t N> inline
constexpr std::size_t static_strlen(char const (&)[N]) { return N; }
template <NSBitmapImageFileType t>
struct suffix_t;
#define DEFINE_SUFFIX(endstring, nstype) \
template <> \
struct suffix_t<nstype> { \
static constexpr std::size_t N = static_strlen(endstring); \
static constexpr char const str[N] = endstring; \
static constexpr NSBitmapImageFileType type = nstype; \
};
DEFINE_SUFFIX("tiff", NSTIFFFileType);
DEFINE_SUFFIX("bmp", NSBMPFileType);
DEFINE_SUFFIX("gif", NSGIFFileType);
DEFINE_SUFFIX("jpg", NSJPEGFileType);
DEFINE_SUFFIX("png", NSPNGFileType);
DEFINE_SUFFIX("jp2", NSJPEG2000FileType);
template <NSBitmapImageFileType nstype>
char const* suffix_value = suffix_t<nstype>::str;
}
}
… see how that works? the nice part is that using it has no runtime overhead, which if your map is static, you can use something like that.
For dynamic flow-control and dispatch, function pointers work; that is what happens automatically if you use polymorphic classes and virtual functions but it seems like you have an architecture in place already that may not be amenable to being redone with such high-modernist architectural notions. I like c++11 lambdas as they solve like 90% of my problems in this arena. Perhaps you can elablrate (I will amend my answer)!
If you only have a small number of indices to support, from 0 to 50, you'll get the best performance if you put your function pointers in an array and not a map.
The syntax is also short:
#include <iostream>
#include <functional>
static void f0() {
std::cout << "f0\n";
}
static void f1() {
std::cout << "f1\n";
}
void main()
{
std::function<void()> f[2] = { f0, f1 };
f[0](); // prints "f0"
f[1](); // prints "f1"
}
Or, if you prefer classes over functions:
#include "stdafx.h"
#include <iostream>
class myfunc {
public:
virtual void run() abstract;
virtual ~myfunc() {}
};
class f0 : public myfunc {
public:
virtual void run() {
std::cout << "f0\n";
}
};
class f1 : public myfunc {
public:
virtual void run() {
std::cout << "f1\n";
}
};
void main()
{
myfunc* f[2] = { new f0(), new f1() };
f[0]->run(); // prints "f0"
f[1]->run(); // prints "f1"
for (int i = 0; i < sizeof(f) / sizeof(f[0]); ++i)
delete f[i];
}
Given some definitions
#include <iostream>
#include <iterator>
#include <algorithm>
#include <stdexcept>
#include <map>
using namespace std;
struct state{
int debug_level = 1;
const char* debug_out = "%s";
} s;
// some functions to call
void SLL(state& s, int, int, int, int){
cout << "SLL";
}
void SLR(state& s, int, int, int, int){
cout << "SLR";
}
void SLT(state& s, int, int, int, int){
cout << "SLT";
}
You can use a Map
auto mappedname2fn = map<string, delctype(SLL)*>{
{"SLL", SLL},
{"SLR", SLR}
};
// call a map function
mappedname2fn["SLR"](s, 1, 2, 3, 4);
If you don't want a map you can use a pre-sorted array for a binary search
Here's a binary search of an array of name, function pairs
template<typename P, int N, typename ...T>
auto callFn(P(&a)[N], string val, T&&... params){
auto it = lower_bound(a, a+N, make_pair(val, nullptr),
[](auto& p1, auto& p2){return p1.first < p2.first;});
if(it==(a+N) || val<it->first) throw logic_error("not found");
return it->second(forward<T>(params)...);
}
So you can set up an array and use that:-
// array sorted in alphabetical order for binary search to work
pair<string, decltype(SLL)*> name2fn[] = {
{"SLL", SLL},
{"SLR", SLR},
{"SLT", SLT}
};
void callFn(string name, state& s, int a, int b, int c, int d){
try{
callFn(name2fn, name, s, a, b, c, d);
}
catch(exception& e){
cout << e.what();
}
}
// call it
callFn("SLL", s, 1, 2, 3, 4);
I come from Java and Ruby so I have a hard time coding simple stuff in c++, c++ being harder to tame...
I want to initialize an array in the class constructor with predefined values that can be accessed by all methods in the class. Yeah, basic stuff.
In other words, I want to do something like this:
Box.h
class SomeClass
{
public:
SomeClass(int something);
SomeMethod();
DoSomething(int thing);
protected:
int _something;
int[] arr;
};
Box.cpp
SomeClass::SomeClass(int something) : something(_something)
{
arr ={16,2,45,65,45};
for (int x = 0; x < 5; x++)
arr[i] = arr[i] * _something;
}
SomeClass::SomeMethod(){
for (int x = 0; x < 5; x++)
DoSomething(arr[i]);
}
SomeClass::DoSomething(int thing){
//whatever
}
How?
#include <iostream>
//#include <initializer_list>
#include <array>
#include <algorithm>
class foo
{
public:
foo() : values({{16,2,45,65,45}})
{
// I left the below commented out in case you want to research more and use other kinds of types for doing it.
//std::initializer_list<int> list = {16,2,45,65,45};
//std::copy(std::begin(list), std::end(list), std::begin(values));
}
void print()
{
std::for_each(std::begin(values), std::end(values),
[](int v) { std::cout << v << ' '; });
}
private:
static const int SIZE = 5;
std::array<int, 5> values;
};
int main()
{
foo fooInstance;
fooInstance.print();
return 0;
}
The above is the best that I could do in a short period of time. I tested with the following compiler. You could use that as a starting point and see if you can learn other ways of doing it. Algorithms such as generate can also be used with lamda expressions in order to generate a controlled set of values (as opposed to a hard coded list as in our examples).
http://www.compileonline.com/compile_cpp11_online.php
You have options for initializing array data members, and two types or array you can use:
Using a C-style array,
struct Foo
{
int a[5] = {1,2,3,4,5}; // initialization at point of declaration
};
struct Bar
{
int a[5];
Bar() : a{1,2,3,4,5} {} // initialization in constructor initialization list
};
Or using an std::array:
struct Foo
{
std::array<int,5> a = {{1,2,3,4,5}}; // initialization at point of declaration
};
struct Bar
{
std::array<int,5> a;
Bar() : a{{1,2,3,4,5}} {} // initialization in constructor initialization list
};
If you can use C++11, there is support for uniform initialization which allows you to assign brace-enclosed lists of values in more contexts than the special case in C.
I have a struct:
typedef struct
{
int nNum;
string str;
}KeyPair;
Let's say I initialize my struct:
KeyPair keys[] =
{ {0, "tester"},
{2, "yadah"},
{0, "tester"}
};
I want to use the initialized values in a function. How do I pass this array struct as a function parameter?
I have:
FetchKeys( KeyPair *pKeys)
{
//get the contents of keys[] here...
}
How about?
template<int N> void FetchKeys(KeyPair const (&r)[N]){}
EDIT 2:
Or even
template<int N> void FetchKeys(KeyPair const (*p)[N])
with the call as
FetchKeys(&keys);
You can do it as #MSalters mentioned, or you can create a std::vector<KeyPair> and pass it to the function. Here is a sample code:
using namespace std;
struct KeyPair
{
int nNum;
string str;
};
void fetchKeys(const vector<KeyPair>& keys)
{
//Go through elements of the vector
vector<KeyPair>::const_iterator iter = keys.begin();
for(; iter != keys.end(); ++iter)
{
const KeyPair& pair = *iter;
}
}
int main()
{
KeyPair keys[] = {{0, "tester"},
{2, "yadah"},
{0, "tester"}
};
//Create a vector out of the array you are having
vector<KeyPair> v(keys, keys + sizeof(keys)/sizeof(keys[0]));
//Pass this vector to the function. This is safe as vector knows
//how many element it contains
fetchKeys(v);
return 0;
}
Should be
// Definition
void FetchKeys( KeyPair *pKeys, int nKeys)
{
//get the contents of keys[] here...
}
// Call
FetchKeys(keys, sizeof(keys)/sizeof(keys[0]));
In c/c++ the name of the array (of any type) represents the address of the first element of the array, so
keys and &keys [0] are same.
You can pass any one of them for KeyPair*.
You just callFetchKeys(keys);
EDIT
Pay attention to declare FetchKeys' return type.
EDIT 2
If you also need the number of items, you add size as FetchKeys input parameters:
void FetchKeys(KeyPair*, size_t size);
and call FetchKeys(keys, sizeof(keys)/sizeof(*keys));
BTW, state all your question by editing your first post if you can.
Depending on what you want to do you can even use boost range and pass it to function as a pair of iterators:
void FetchKeys(KeyPair *begin, KeyPair *end)
FetchKeys(boost::begin(keys), boost::end(keys));
See this answer: How can I pass an array by reference to a function in C++?
Wrap it in a structure, nice and easy..
#include <iostream>
struct foo
{
int a;
int b;
};
template <typename _T, size_t _size>
struct array_of
{
static size_t size() { return _size; }
_T data[_size];
};
template <typename _at>
void test(_at & array)
{
cout << "size: " << _at::size() << std::endl;
}
int main(void)
{
array_of<foo, 3> a = {{ {1,2}, {2,2}, {3,2} }};
test(a);
}
EDIT: URGH, I can't see the toolbar to format the code correctly, hopefully the tags works..
i use VS 2008, and this works fine for me.
#include "stdafx.h"
typedef struct
{
int nNum;
CString str;
}KeyPair;
void FetchKeys( KeyPair *pKeys);
int _tmain(int argc, _TCHAR* argv[])
{
KeyPair keys[] =
{ {0, _T("tester")},
{2, _T("yadah")},
{0, _T("tester")}
};
FetchKeys(keys); //--> just pass the initialized variable.
return 0;
}
void FetchKeys(KeyPair *pKeys)
{
printf("%d, %s\n",pKeys[0].nNum, pKeys[0].str);
}
I don't understand the difficulty. correct me if i'm wrong. To keep it simple, i avoided using vectors, templates and etc.
edit: to know size of struct, you can pass one more arg.
I need to implement an std::map with <std::string, fn_ptr> pairs. The function pointers are pointers to methods of the same class that owns the map. The idea is to have direct access to the methods instead of implementing a switch or an equivalent.
( I am using std::string as keys for the map )
I'm quite new to C++, so could anyone post some pseudo-code or link that talks about implementing a map with function pointers? ( pointers to methods owned by the same class that owns the map )
If you think there's a better approach to my problem, suggestions are also welcome.
This is about the simplest I can come up with. Note no error checking, and the map could probably usefully be made static.
#include <map>
#include <iostream>
#include <string>
using namespace std;
struct A {
typedef int (A::*MFP)(int);
std::map <string, MFP> fmap;
int f( int x ) { return x + 1; }
int g( int x ) { return x + 2; }
A() {
fmap.insert( std::make_pair( "f", &A::f ));
fmap.insert( std::make_pair( "g", &A::g ));
}
int Call( const string & s, int x ) {
MFP fp = fmap[s];
return (this->*fp)(x);
}
};
int main() {
A a;
cout << a.Call( "f", 0 ) << endl;
cout << a.Call( "g", 0 ) << endl;
}
A template implementation could look like:
class Factory {
public:
enum which {
foo, bar, baz
};
template<which w>
A* newA(...);
...
};
template<Factory::which w>
A* Factory::newA(...) {
/* default implementation */
throw invalid_argument();
}
template<>
A* Factory::newA<Factory::foo>(...) {
/* specialization for a 'foo' style A */
...
}
....
This requires that the value used to determine which newA is called be known at compile time. You could potentially use a const char * as the template parameter, but it's not guaranteed to work on all compilers.
Yet another option is to create helper factories, one for each factory creation method, and store those in the map. This isn't a huge advantage over storing method pointers, but does let you define a default creation method and simplifies fetching things from the map (there's no need to check that the key exists, because you'll get a default factory). On the downside, an entry for each unknown key would be added to the map.
Also, if you use an enum rather than a string for the key type, you shouldn't need to worry about checking whether a key exists in the map. While it's possible for someone to pass an invalid enum key to newA, they'd have to explicitly cast the argument, which means they're not going to do it by accident. I'm having a hard time imagining a case where someone would purposefully cause a crash in newA; the potential scenarios involve security, but an application programmer could crash the app without using your class.
Since C++14, we can use a generic lambda to get rid easily of pointers to member methods.
It follows a minimal, working example of a forward function made up with a generic lambda function:
#include<utility>
#include<map>
#include<string>
#include<iostream>
struct SomeClass { };
struct SomeOtherClass { };
struct Test {
void test(SomeClass) { std::cout << "SomeClass" << std::endl; }
void test(SomeOtherClass) { std::cout << "SomeOtherClass" << std::endl; }
};
int main() {
Test test;
auto l = [&test](auto c){ test.test(c); };
std::map<std::string, decltype(l)> m;
m.emplace("foo", l);
m.emplace("bar", l);
m.at("foo")(SomeClass{});
m.at("bar")(SomeOtherClass{});
}
Another option is to use delegates as oppose to function pointers. This delegate implementation is pretty fast, supports polymorphisms, and plays well with stl containers.
You could have something like:
class MyClass {
public:
// defines
typedef fastdelegate::FastDelegate2<int, int, int> MyDelegate;
typedef std::map<std::string, MyDelegate> MyMap;
// populate your map of delegates
MyClass() {
_myMap["plus"] = fastdelegate::MakeDelegate(this, &Plus);
_myMap["minus"] = fastdelegate::MakeDelegate(this, &Minus);
}
bool Do(const std::string& operation, int a, int b, int& res){
MyMap::const_iterator it = _myMap.find(operation);
if (it != _myMap.end()){
res = it.second(a,b);
return true;
}
return false;
}
private:
int Plus (int a, int b) { return a+b; }
int Minus(int a, int b) { return a-b; }
MyMap _myMap;
};