I have created a class in C++. Each object corresponds with an I/O pin on a microcontroller. I can create an array of the objects and then set each pin to an output with a for loop. I would like to be able to set multiple pins to an output at the exact same time. This can be done with the hardware.
I am trying to create a method that works on an array of objects. You would use it like this:
Pin myPins[] = {0,1,2};
myPins.setOuput();
Basically I want to create a method that works on an array of objects. Is it possible to create a setOuput method like this? If yes, how? Thanks.
Update 1
New non-member method
void setOutput(Pin pins[], int size) {
volatile uint8_t* _DDR = pins[0].getDDR();
uint8_t _offset = 0;
for (int i = 0; i < size; i++) {
_offset |= pins[i].getOffset();
}
DDR_HIGH;
}
I am using the _ in the names so that my existing macro works. Not great but less code.
Nope, you cannot add a method to a classic array the way you intend to. However, you could create a class that inherits from, say, a std::vector<Pin>, and add methods to it, like this:
class Pins : public std::vector<Pin>
{
public:
void setOutput() { /* your code here */ }
};
That way, using C++11's uniform initialization, you could use a similar syntax:
Pins myPins = {0, 1, 2};
myPins.setOutput();
Edit: as per the comments, subclass a STL container is a quick and dirty solution and not the best idea. You could, however, create your own wrapper class very simply:
class Pins
{
std::vector<Pin> mPins;
public:
Pins (std::initializer_list<Pin> pins) : mPins(pins)
{ }
void setOutput()
{
cout << "Pins in this pinset:" << endl;
for (Pin & p : mPins)
{
cout << "\t" << p << endl;
}
}
};
That works exactly the same:
Pins myPins = {0, 1, 2};
myPins.setOutput();
Most probably your setOutput member function is reading some possibly multi byte value, changing a bit depending on the pin, and writing it back.
C++ arrays can't have member functions.
To achieve a similar effect, you should split the work your original setOutput is doing:
Read some hardware config
Do the bit twiddling
Apply the changes
Then you can let multiple pins do their bit twiddling before applying the final output.
Example:
Pin::Config cfg = Pin::read_config();
// the following could also happen in a loop over an array.
cfg = pin1.enableOutput(cfg);
cfg = pin4.enableOutput(cfg);
// or pass by reference and mutate, if you
// want a less functional style
// e.g. pinN.enableOutput(cfg)!
Pin::write_config(cfg);
This way you still have good encapsulation, but better control. Then you can write a free function to operate on arrays, vectors or whatever collection of pins, if needed:
template<typename It>
void setOutputPins(It start, It end) {
Pin::Config cfg = Pin::read_config();
for (; start != end; ++start) {
cfg = (*start).enableOutput(cfg);
}
Pin::write_config(cfg);
};
Using it with C arrays:
Pin array[5]; // or a pointer for dynamic arrays
// ...
setOutputPins(array, array + size);
Don't make everything OO. It'll make your life harder.
[...] a function that returns the offset value for each Pin [...]. Then I bitwise or them all together.
So you don't even need that reading step. And since you bitwise or them, you could even do something like this:
Pin::write_config(pin1.output_mask() | pin4.output_mask());
You can make the function generic, too: Or pass a member function pointer:
template<typename It>
void setPins(It start, It end, Pin::Config (Pin::*fn)(void)) {
Pin::Config cfg = 0; // identity for bitwise or
for (; start != end; ++start) {
cfg |= ((*start).*fn)();
}
Pin::write_config(cfg);
};
And the pass a pointer to the member function you want to invoke:
setPins(array, array + size, &Pin::asInput);
Example here.
Related
Guys I have a function like this (this is given and should not be modified).
void readData(int &ID, void*&data, bool &mybool) {
if(mybool)
{
std::string a = "bla";
std::string* ptrToString = &a;
data = ptrToString;
}
else
{
int b = 9;
int* ptrToint = &b;
data = ptrToint;
}
}
So I want to use this function in a loop and save the returned function parameters in a vector (for each iteration).
To do so, I wrote the following struct:
template<typename T>
struct dataStruct {
int id;
T** data; //I first has void** data, but would not be better to
// have the type? instead of converting myData back
// to void* ?
bool mybool;
};
my main.cpp then look like this:
int main()
{
void* myData = nullptr;
std::vector<dataStruct> vec; // this line also doesn't compile. it need the typename
bool bb = false;
for(int id = 1 ; id < 5; id++) {
if (id%2) { bb = true; }
readData(id, myData, bb); //after this line myData point to a string
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
}
}
Or is there a better way to do that without template? I used c++11 (I can't use c++14)
The function that you say cannot be modified, i.e. readData() is the one that should alert you!
It causes Undefined Behavior, since the pointers are set to local variables, which means that when the function terminates, then these pointers will be dangling pointers.
Let us leave aside the shenanigans of the readData function for now under the assumption that it was just for the sake of the example (and does not produce UB in your real use case).
You cannot directly store values with different (static) types in a std::vector. Notably, dataStruct<int> and dataStruct<std::string> are completely unrelated types, you cannot store them in the same vector as-is.
Your problem boils down to "I have data that is given to me in a type-unsafe manner and want to eventually get type-safe access to it". The solution to this is to create a data structure that your type-unsafe data is parsed into. For example, it seems that you inteded for your example data to have structure in the sense that there are pairs of int and std::string (note that your id%2 is not doing that because the else is missing and the bool is never set to false again, but I guess you wanted it to alternate).
So let's turn that bunch of void* into structured data:
std::pair<int, std::string> readPair(int pairIndex)
{
void* ptr;
std::pair<int, std::string> ret;
// Copying data here.
readData(2 * pairIndex + 1, ptr, false);
ret.first = *reinterpret_cast<int*>(ptr);
readData(2 * pairIndex + 2, ptr, true);
ret.second = *reinterpret_cast<std::string*>(ptr);
}
void main()
{
std::vector<std::pair<int, std::string>> parsedData;
parsedData.push_back(readPair(0));
parsedData.push_back(readPair(1));
}
Demo
(I removed the references from the readData() signature for brevity - you get the same effect by storing the temporary expressions in variables.)
Generally speaking: Whatever relation between id and the expected data type is should just be turned into the data structure - otherwise you can only reason about the type of your data entries when you know both the current ID and this relation, which is exactly something you should encapsulate in a data structure.
Your readData isn't a useful function. Any attempt at using what it produces gives undefined behavior.
Yes, it's possible to do roughly what you're asking for without a template. To do it meaningfully, you have a couple of choices. The "old school" way would be to store the data in a tagged union:
struct tagged_data {
enum { T_INT, T_STR } tag;
union {
int x;
char *y;
} data;
};
This lets you store either a string or an int, and you set the tag to tell you which one a particular tagged_data item contains. Then (crucially) when you store a string into it, you dynamically allocate the data it points at, so it will remain valid until you explicitly free the data.
Unfortunately, (at least if memory serves) C++11 doesn't support storing non-POD types in a union, so if you went this route, you'd have to use a char * as above, not an actual std::string.
One way to remove (most of) those limitations is to use an inheritance-based model:
class Data {
public:
virtual ~Data() { }
};
class StringData : public Data {
std::string content;
public:
StringData(std::string const &init) : content(init) {}
};
class IntData : public Data {
int content;
public:
IntData(std::string const &init) : content(init) {}
};
This is somewhat incomplete, but I think probably enough to give the general idea--you'd have an array (or vector) of pointers to the base class. To insert data, you'd create a StringData or IntData object (allocating it dynamically) and then store its address into the collection of Data *. When you need to get one back, you use dynamic_cast (among other things) to figure out which one it started as, and get back to that type safely. All somewhat ugly, but it does work.
Even with C++11, you can use a template-based solution. For example, Boost::variant, can do this job quite nicely. This will provide an overloaded constructor and value semantics, so you could do something like:
boost::variant<int, std::string> some_object("input string");
In other words, it's pretty what you'd get if you spent the time and effort necessary to finish the inheritance-based code outlined above--except that it's dramatically cleaner, since it gets rid of the requirement to store a pointer to the base class, use dynamic_cast to retrieve an object of the correct type, and so on. In short, it's the right solution to the problem (until/unless you can upgrade to a newer compiler, and use std::variant instead).
Apart from the problem in given code described in comments/replies.
I am trying to answer your question
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
Before that you need to modify vec definition as following
vector<dataStruct<void>> vec;
Now you can simple push element in vector
vec.push_back({id, &mydata, bb});
i have tried to modify your code so that it can work
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
struct dataStruct
{
int id;
T** data;
bool mybool;
};
void readData(int &ID, void*& data, bool& mybool)
{
if (mybool)
{
data = new string("bla");
}
else
{
int b = 0;
data = &b;
}
}
int main ()
{
void* mydata = nullptr;
vector<dataStruct<void>> vec;
bool bb = false;
for (int id = 0; id < 5; id++)
{
if (id%2) bb = true;
readData(id, mydata, bb);
vec.push_back({id, &mydata, bb});
}
}
Basically i've only realised that the way i've coded my project i need to implement some form of lookup table, now i have never done this before and therefore don't know how to do it and googling doesn't really give a clear set of instructions
I need the lookup table so that a user can input a function into the command line and then pass in parameters to that function, but no idea where to start
You could do something like this in order to create a lookup (dispatch) table:
(Notice: This is how to implement a dispatch table and it is both C and C++ compartible. There are other-and maybe easier ways to do this in C++ without reinventing the wheel, like using some containers etc).
#include <iostream>
using namespace std;
// Arrays start from 0.
// This is used for code
// readability reasons.
#define CASE(X) X-1
typedef void (*chooseCase)();
// Functions to execute each case.
// Here, I am just printing
// different strings.
void case1(){
cout<< "case1" << endl;
}
void case2(){
cout<< "case2" << endl;
}
void case3(){
cout<< "case3" << endl;
}
void case4(){
cout<< "case4" << endl;
}
//Put all the cases in an array.
chooseCase cases[] = {
case1, case2, case3, case4
};
int main()
{
//You can call each scenario
//by hand easily this way:
cases[CASE(1)]();
cout << endl;
//Idea: You can even set in another
// array a sequence of function executions desired.
int casesSequence[] = {
CASE(1), CASE(2), CASE(3), CASE(4),CASE(3),CASE(2),CASE(1)
};
//Execute the functions in the sequence set.
for(int i = 0; i < (sizeof(casesSequence)/sizeof(int)); ++i){
cases[casesSequence[i]]();
}
return 0;
}
(Based on: Adding split-screen multiplayer to c++ game)
Now about the program input, you could map the name of your function to get the index for example and you could apply the example above to parameterized functions and you can also use this in situations that functions are parameterized.
In this case,please take into consideration that all functions should obey to the function pointer signature in order to use it in this example. Otherwise, you have to do more tricky things (like using a void* argument and passing an arguments struct "instance" pointer to each function).
I don't know exactly your requirements, but I could imagine sth like this:
You might want to have a look into C++ function pointers. You could make an own struct that holds:
name of a function
pointer to that function
vector of variants (for example from boost or write yourown) to hold the arguments
validate function to see if the arguments and function pointer fit
Create for each function that the user can call a an instance of this struct. Display those to the user and let him choose. In the second step, let him enter the values for the arguments.
You can use std::map<std::string, functype> where functype is a typedef'd function pointer, or even a boost::function<> type.
std::map<std::string, functype> funcs;
void call_user_func(const std::string &user_input, const std::string &arg1, const std::string & arg2)
{
functype f = funcs.at(user_input);
f(arg1, arg2);
}
I give you and example on Arduino that is almost the same C/C++ code analogy
float cosLUT[(int) (360.0 * 1 / 0.5)] ;
const float DEG2RAD = 180 / PI ;
const float cosinePrecision = 0.5;
const int cosinePeriod = (int) (360.0 * 1 / cosinePrecision);
void setup()
{
initCosineLUT();
}
void loop()
{
// nothing for now!
}
void initCosineLUT(){
for (int i = 0 ; i < cosinePeriod ; i++)
{
cosLUT[i] = (float) cos(i * DEG2RAD * cosinePrecision);
}
}
Lookup tables are one of the most powerful tricks in the programming universe.
They are arrays containing precalculated values and thus replace heavy runtime
calculations by a simpler array index operation. For instance, imagine you want to
track positions of something by reading distances coming from a bunch of distance
sensors. You'll have trigonometric and probably power calculations to perform.
Because they can be time consuming for your processor, it would be smarter and
cheaper to use array content reading instead of those calculations. This is the usual
illustration for the use of lookup tables.
Given a C++ class with assorted member data values and a static int counter, I'd like to have a clear() function that can walk all the elements of an array of these class objects clearing their data members.
So, for example, a class that looks like this and holds a chip's version information (yes, I know I probably need more setters and getters):
class __STA_version_t
{
public:
__STA_version_t() { count++; };
~__STA_version_t() {};
void setVerString( char* x ) { strncpy( verString, x, sizeof(verString)); verString[sizeof(verString)-1] = 0
void clearVerString() { memset( verString, 0x0, sizeof(verString) ); }
char* getVerString() { return verString; }
bool hasVersion() { return verString[0]; }
void clear()
{
for ( int i = 0; i < count; i++ )
{
// what goes here?
}
}
private:
static int count; // how many of these objects exist, need to know for clear().
char verString[20]; // station version as a string
UINT8 major_ver; // major version identifier (3 bits)
UINT8 minor_ver; // minor version identifier (6 bits)
UINT8 revision; // revision identifier (4 bits)
UINT8 chip_ident; // target chip identifier (3 bits)
};
Elsewhere initialize count thusly:
__STA_version_t::count = 0;
Now, create an array of there objects:
__STA_version_t versions[10];
First, just checking, count should equal 10 after this instantiation, right?
In the clear() function, I'd like to say something like:
this[i]->clearVerString();
this[j]->revision = 0;
// etc.
to clear each data member of each element of the array.
Can this be made to work? How?
The issue is that the class can't see outside its boundaries and the container is outside of the class' boundary.
You should use a standard container. Make the clear method clear data members in the class.
The standard containers have methods for determining the number of items.
See std::vector, std::list, std::map, etc.
What you are trying to do is not very "object oriented" IMO. I would argue that the class clear() member function you are trying to implement here should only clear the data of the instantiated object on which it is invoked. What you are trying to do is clear the data in all instantiations of your class, via calling clear() on any/one of them only?
A better approach here would be to store your objects in a std::vector<__STA_version_t>, and then write a static function on your class that either takes the vector as a parameter (ideally), or can access it globally somehow, called maybe clearAll(). Have that function iterate through the vector and call clear() on each object in the vector. The clear() function would then simply call clearVerString() etc on itself - eg:
this->clearVerString();
this->revision = 0; and so on (noting that you don't actually need to use the this pointer if you don't want to).
How it is possible to provide all three functions: msgpack_pack, msgpack_unpack and msgpack_object (also, what are meanings of them, exactly?) for a user-defined C++ class (in the same way MSGPACK_DEFINE does it for non-array POD/UD types) containing Plain Old Data arrays (such as dobule[] or char[]), so my class will play nicely with higher-level classes, containg this class in map or a vector?
Is there any examples of implementing them for your own class or at least msgpack C++ api documentation?
The only link to possible api reference i've found was http://redmine.msgpack.org/projects/msgpack/wiki ; but it is dead now.
Say, i have a struct like
struct entity {
const char name[256];
double mat[16];
};
What would be a msgpack_* member functions for it?
Thanks to guy who -1'd my question, i felt grievance and explored the actual undocumented codebase of msgpack. Here is the example of mentioned earlier functions with sort of explanation, in amount of my (vastly incomplete due to missing docs) understanding:
struct entity {
char name[256];
double mat[16];
// this function is appears to be a mere serializer
template <typename Packer>
void msgpack_pack(Packer& pk) const {
// make array of two elements, by the number of class fields
pk.pack_array(2);
// pack the first field, strightforward
pk.pack_raw(sizeof(name));
pk.pack_raw_body(name, sizeof(name));
// since it is array of doubles, we can't use direct conversion or copying
// memory because it would be a machine-dependent representation of floats
// instead, we converting this POD array to some msgpack array, like this:
pk.pack_array(16);
for (int i = 0; i < 16; i++) {
pk.pack_double(mat[i]);
}
}
// this function is looks like de-serializer, taking an msgpack object
// and extracting data from it to the current class fields
void msgpack_unpack(msgpack::object o) {
// check if received structure is an array
if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
const size_t size = o.via.array.size;
// sanity check
if(size <= 0) return;
// extract value of first array entry to a class field
memcpy(name, o.via.array.ptr[0].via.raw.ptr, o.via.array.ptr[0].via.raw.size);
// sanity check
if(size <= 1) return;
// extract value of second array entry which is array itself:
for (int i = 0; i < 16 ; i++) {
mat[i] = o.via.array.ptr[1].via.array.ptr[i].via.dec;
}
}
// destination of this function is unknown - i've never ran into scenary
// what it was called. some explaination/documentation needed.
template <typename MSGPACK_OBJECT>
void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const {
}
};
my question is about how to template'ize the name of a class member that should be used.
Maybe a simplified & pseudo example:
/**
Does something with a specified member of every element in a List.
*/
template<membername MEMBER> // <-- How to define such thing?
void doSomething(std::vector<MyClass> all){
for( i=0; i < all.size(); i++)
all[i].MEMBER++; // e.g.; use all[i].MEMBER in same way
}
and
class MyClass{
public:
int aaa, bbb, ccc;
}
and the application:
main(){
vector<MyClass> all = ....
// applicate doSomething() to all aaa's
doSomething<aaa>(all); // or:
doSomething<MyClass::aaa>(all); // or:
doSomething<?????>(all);
}
How should the template definition looks like, that I can switch which member variable (aaa, bbb or ccc) of MyClass is accessed/modified in doSomething(.) ?
In my real world task all MEMBER are of same type, as above.
Thanks,
Tebas
Template parameters are restricted to types, integer constants, pointers/references to functions or objects with external linkage and member pointers -- but no identifiers.
But you could use a member pointer as template parameter:
template<int MyClass::* MemPtr>
void doSomething(std::vector<MyClass> & all) {
for( i=0; i < all.size(); i++)
(all[i].*MemPtr)++;
}
:
doSomething<&MyClass::aaa>(all);
Note that I changed the doSomething function to take a reference instead of accepting the vector by value.
sellibitze's solution is fine (though to be honest not very: see my edit), only it limits you to using only members of type int. A more general solution would be this (although the member is NOT a template parameter here)
#include <vector>
struct MyClass
{
int i;
char c;
};
template <class T>
void DoSomething(std::vector<MyClass>& all, T MyClass::* MemPtr)
{
for(std::vector<MyClass>::size_type i = 0; i < all.size(); ++i)
(all[i].*MemPtr)++;
}
int main()
{
std::vector<MyClass> all;
DoSomething(all, &MyClass::i);
DoSomething(all, &MyClass::c);
}
EDIT:
Also please note that it is not generally a good idea for a pointer to member to be a template parameter inasmuch as only such pointers that are known compile-time can be passed, that is you can't determine the pointer runtime and then pass it as a template param.
I would use lambdas to solve this problem. Something like this:
#include <vector> // vector
#include <algorithm> // for_each
#include <functional> // function
struct MyClass {
void func1() const { std::cout << __FUNCTION__ << std::endl; }
void func2() const { std::cout << __FUNCTION__ << std::endl; }
};
void doSomething(std::vector<MyClass> all, std::function<void (MyClass& m)> f)
{
std::for_each(all.begin(), all.end(), f);
}
int main()
{
std::vector<MyClass> all;
all.push_back(MyClass());
// apply various methods to each MyClass:
doSomething(all, [](MyClass& m) { m.func1(); });
doSomething(all, [](MyClass& m) { m.func2(); });
}
Of course in this case the function doSomething is unnecessary. I could just as simply call for_each directly on all.
I realize this question is a bit old, but none of the answers use the method I have developed, and I would like to share it.
First, in C++ we typically are discouraged from directly accessing member variables and encouraged to provide setters/getters to help enforce hiding of information.
Second, while C++ goes a long way towards eliminating use of macros, they can still accomplish a lot of things that are difficult (or near impossible) with templates and classes.
The following uses a macro to create typed setters & getters for fields in a container member within a class:
//
// Bit(n) -- sets 'n'th bit.
// Bit(0) == 0x1 (b0000001),
// Bit(1) == 0x2 (b0000010),
// Bit(2) == 0x4 (b0000100),
// Bit(3) == 0x8 (b0001000), etc.
//
#define Bit(n) (1 << (n))
//
// BitMask(n) -- creates mask consisting of 'n' bits.
// BitMask(0) == 0x0 (b00000000),
// BitMask(1) == 0x1 (b00000001),
// BitMask(2) == 0x3 (b00000011),
// BitMask(3) == 0x7 (b00000111), etc.
//
#define BitMask(n) (Bit(n) - 1)
//
// BitRange(n, m) -- creates mask consisting of bits between n & m, inclusive.
// BitRange(0, 3) == 0x0f (b00001111),
// BitRange(2, 5) == 0x3c (b00111100),
// BitRange(6, 1) == 0x7e (b01111110), etc.
//
//
#define BitRange(n,m) (BitMask(n) ^ BitMask(m))
#define namedBitField(name, container, start, end, EnumType) \
EnumType name() const \
{return \
(EnumType) \
((container & BitRange(start,end)) \
>> start); \
}; \
void name(EnumType v) {container |= (v << start);}; \
class myTest
{
public:
enum vSet1
{
a = 1,
b = 2,
};
private:
unsigned long holder;
public:
myTest() {};
namedBitField(set1, holder, 0, 3, vSet1);
namedBitField(set2, holder, 4, 5, vSet1);
};
myTest mt;
The namedBitField() macro takes the name for the getter/setter pair, the target container -- holder in this example, the bitfield start/end, and the EnumType that is to be used for values in the bitfield.
If I now use the setter/getter pairs named set1() & set2() in the above example, and attempt to pass POD (plain-old-data) numbers I will get a warning from the compiler.
mt.set1(22); // compiler warns here.
mt.set1();
mt.set2(myTest::vSet1::a); // no warnings.
mt.set2();
No, it is not a "typed bitfield", but it is the next best thing.
No, it is not quite as easy to use as defining bitfields in a struct, but this way you get strong typing via the setters/getters.
Now, you could define the bitfields in structs, make them private, and access them via setters/getters as well, but then the information about where the bits are located is separated from the setters/getters which logically are tied to that information, and as several responders above have pointed out, each C++ compiler can put the bits anywhere they want, so without looking at generated assembler -- or testing on hardware if you are brave -- you cannot be certain things are happening the way you want.
The way the setters/getters created by namedBitField() manipulate the bits in a well-defined order and guarantee bit-order within container, so you can now use the code cross-platform for accessing I/O registers.
Note: in my example I use 'name' as both setter and getter with compiler sorting it out based on use. Some may prefer 'get_name' and 'set_name'. YMMV.
Since the getters/setters are public, and as long as the things you are iterating all derive from the same base class, you can now iterate across the items in a vector -- as above -- and get type-safe getting/setting for the values used in the iteration.