问题
I have a class that takes a "list" of pins as argument in the constructor.
Right now, this "list" is just a const array (const unsigned int (&pins)[N]
).
I'd like to overload the constructor in such a way that you can use an initializer_list as well as a (const) array.
I can get it working with separate classes, but I'm unable to combine them.
The basic structure of my test class:
#include <iostream>
#include <cstring>
using namespace std;
class X
{
public:
X(... pins);
~X();
void print() {
for (unsigned int i = 0; i < length; i++)
cout << pins[i] << ' ';
}
private:
(const) unsigned int *pins;
const size_t length;
};
Class A (using std::initializer_list)
public:
A(initializer_list<unsigned int> pins)
: length(pins.size()) {
this->pins = (unsigned int *)malloc(sizeof(unsigned int) * pins.size());
memcpy(this->pins, pins.begin(), sizeof(unsigned int) * pins.size());
}
~A() {
free(pins);
}
private:
unsigned int *pins;
Class B (using an array)
public:
template <size_t N>
B(unsigned int (&pins)[N])
: length(N) {
this->pins = pins;
}
private:
unsigned int *pins;
Class C (using a const array)
public:
template <size_t N>
C(const unsigned int (&pins)[N])
: length(N) {
this->pins = pins;
}
private:
const unsigned int *pins;
This allows me to do things like:
A a({1, 2, 3});
unsigned int pb[] = {4, 5, 6};
B b(pb);
const unsigned int pc[] = {7, 8, 9};
C c(pc);
a.print();
b.print();
c.print();
And this prints 1 2 3 4 5 6 7 8 9
as expected.
How can I combine these different constructors in one class? I want to be able to initialize an object in either of the three ways shown above.
If I make pins
a const
, I can't do things like memcpy(pins, ...)
, and if I don't make it a const
, I can't use a const array as argument for the constructor.
(The target platform is Arduino, so most fancy and memory-intensive C++11 tricks are not supported.)
回答1:
Something along these lines, perhaps:
class X
{
public:
X(std::initializer_list<unsigned int> aPins)
: storage(aPins), length(aPins.size()) {
pins = length ? &storage[0] : nullptr;
}
template <size_t N>
X(unsigned int (&aPins)[N])
: length(N) {
pins = aPins;
}
template <size_t N>
X(const unsigned int (&aPins)[N])
: length(N) {
pins = aPins;
}
void print() {
for (unsigned int i = 0; i < length; i++)
std::cout << pins[i] << ' ';
}
private:
const unsigned int* pins;
const size_t length;
std::vector<unsigned int> storage;
};
Demo
来源:https://stackoverflow.com/questions/45772095/c-overload-constructor-with-const-array-and-initializer-list