假設channelList
是空值終止,並且_channelList
應該是一個類的成員,你可以試試這個:
#include <algorithm> // For std::copy().
// ...
template<size_t N> Node::Node(bool isBase, const int (&channelList)[N]) : _isBase(isBase)
{
std::copy(std::begin(channelList), std::end(channelList), std::begin(_channelList));
}
除非我錯過了一些東西,應該使用任何大小的C型int數組,並將其複製到_channelList
。如果傳遞的數組大於_channelList
,則可能會導致問題。如果可能的話,如果尺寸是預定的,則最好使用std::array
,如果不是,則使用std::vector
。
如果大小是固定的:
#include <array>
#include <algorithm> // For std::copy() and std::fill().
const size_t _sz = [whatever];
// Simple way of setting size, but not the best. See below.
class Node
{
bool _isBase;
std::array<int, _sz> _channelList;
public:
Node(bool isBase, const int (&channelList)[_sz]);
Node(bool isBase, const std::array<int, _sz>& channelList);
// ...
};
/* Alternatively, you can code the size into the class as a magic number (not a good idea),
* or better yet, make it a template parameter for the class:
* template<size_t _sz> class Node
* {
* bool _isBase;
* std::array<int, _sz> _channelList;
*
* public:
* Node(/ * parameters * /);
*
* template<size_t N>
* Node(/ * parameters * /);
* // ...
* };
* When using the class, you would declare an instance as "Node<SIZE>", where "SIZE" is the
* desired size.
*
* Note that if you make the size a template parameter, and define the member functions
* outside of the class' definition, you have to put the same template at the start of each
* member function:
* template<size_t _sz> Node<_sz>::Node(/ * parameters * /)
* {
* // ...
* }
* This also applies to templated member functions, which will have two sets of template
* parameters.
* template<size_t _sz> template<size_t N> Node<_sz>::Node(/ * parameters * /)
* {
* // ...
* }
*/
// Constructor initialising from C array, if you need to work with preexisting code.
Node::Node(bool isBase, const int (&channelList)[_sz]) : _isBase(isBase)
{
std::copy(std::begin(channelList), std::end(channelList), std::begin(_channelList));
}
// Constructor using std::array.
Node::Node(bool isBase, const std::array<int, _sz>& channelList)
: _isBase(isBase), _channelList(channelList)
{
// Initialisation list handles everything.
}
// Note, however, that this will cause issues if the size of channelList doesn't
// necessarily match the size of _channelList. To solve this, we can change Node as
// follows:
// (Note that delegation requires a C++11-compatible compiler.)
#include <type_traits> // For std::integral_constant, std::true_type, and std::false_type.
class Node {
bool _isBase;
std::array<int, _sz> _channelList;
// Actual constructors (C-style array):
template<size_t N>
Node(std::true_type x, bool isBase, const int (&channelList)[N]);
template<size_t N>
Node(std::false_type x, bool isBase, const int (&channelList)[N]);
// Actual constructors (std::array):
template<size_t N>
Node(std::true_type x, bool isBase, const std::array<int, N>& channelList);
template<size_t N>
Node(std::false_type x, bool isBase, const std::array<int, N>& channelList);
public:
// Public constructors, delegate to one of the actual constructors.
// C-style array:
template<size_t N>
Node(bool isBase, const int (&channelList)[N]);
// std::array:
template<size_t N>
Node(bool isBase, const std::array<int, N>& channelList);
// ...
};
/* Now, these constructors are easy enough to make.
* I'll provide an example using C-style arrays. To make versions that take a
* std::array instead, change the parameter:
* const int (&channelList)[N]
* to:
* const std::array<int, N>& channelList
* The constructors should work properly with either kind of array.
*/
// Check if passed array is smaller than or equal to _sz, or if it's larger..
template<size_t N> Node::Node(bool isBase, const int (&channelList)[N])
: Node(std::integral_constant<bool, N <= _sz>{}, isBase, channelList) { }
// N is smaller than or equal to _sz.
template<size_t N> Node::Node(std::true_type x, bool isBase, const int (&channelList)[N])
: _isBase(isBase)
{
// Copy channelList into _channelList.
std::copy(std::begin(channelList), std::end(channelList), std::begin(_channelList));
// Fill empty space at the end of _channelList.
std::fill(&(_channelList[N]), std::end(_channelList), '\0');
}
// N is larger than _sz.
template<size_t N> Node::Node(std::false_type x, bool isBase, const int (&channelList)[N])
{
// Handle appropriately.
}
這應該讓你得到你想要的功能。 [請注意,您也可以用上面的代表團,true_type
和false_type
建設者,以填補C風格的數組以及std::array
S,如果你需要使用它們。]
如果大小不固定:
#include <vector>
#include <algorithm>
class Node {
bool _isBase;
std::vector<int> _channelList;
public:
template<size_t N>
Node(bool isBase, const int (&channelList)[N]);
// ...
};
template<size_t N> Node::Node(bool isBase, const int (&channelList)[N]) : _isBase(isBase)
{
_channelList.assign(std::begin(channelList), std::end(channelList));
}
// You can also define a constructor that takes a std::array<int, N>, if you
// so desire. Again, the only change needed is the parameter itself.
作爲向量的長度可以在運行時改變,我們可以使用vector::assign
分配空間並存儲的channelList
整體。
不管_channelList
是否被存儲爲C陣列,std::array
,或std::vector
,它相對容易定義getter和setter。
吸氣(整個事情):
// All of the following use this class definition, with comments identifying which
// functions use which parts.
// Note that the trailing "const" in each getter signature indicates that the function
// cannot be used to modify the instance. It's optional, but useful to include.
class Node {
// Return C array (either way).
int _channelListC[_sz];
// Return std::array.
std::array<int, _sz> _channelListSArr;
// Return std::vector.
std::vector<int> _channelListSVec;
// Return C array the readable way.
typedef int _channelListC_t[_sz];
// C++11 alternative typedef:
using _channelListC_t = decltype(_channelList);
// The C++11 version is safer, as "decltype(_channelList)" won't break if you change
// _channelList's implementation.
// If you need to return the entire array, it may be a good idea to make this a public
// typedef, so it's easier & safer to declare a variable you can return it to.
public:
// Return C array the ugly way.
const int (&getChannelListCUgly() const)[_sz];
// Return C array the readable way.
const _channelListC_t& getChannelListCReadable() const;
// Return C array the readable C++11 way.
auto getChannelListCReadableCPP11() const -> const int(&)[_sz];
// Return std::array.
const std::array<int, _sz>& getChannelListSArr() const;
// Return std::vector.
const std::vector<int>& getChannelListSVec() const;
};
// Return C array:
/* Note that you can't return an array from a function. However, you can return a pointer
* or reference to an array, depending on whether you use * or & in the signature.
*/
// The ugly way:
const int (&Node::getChannelListCUgly() const)[_sz]
{
return _channelList;
}
// The readable way:
const Node::_channelListC_t& Node::getChannelListCReadable() const
{
return _channelList;
}
// The new readable way, as of C++11:
auto getChannelListCReadableCPP11() const -> const int(&)[_sz]
{
return _channelList;
}
// Return std::array:
const std::array<int, _sz>& Node::getChannelListSArr() const
{
return _channelList;
}
// Return std:;vector:
const std::vector<int>& getChannelListSVec() const
{
return _channelList;
}
注意,據我所知,C風格的數組以這種方式返回必須存儲在一個參考變量。
Node::_channelListC_t& arr = nodeInstance.getChannelListCUgly();
吸氣劑(單個元件):
// C array or std::array:
int Node::getChannelListArrElement(int index) const
{
if (index < _sz)
{
// index is valid, return element.
return _channelList[index];
}
else
{
// index >= _sz, and is invalid.
// Handle accordingly.
}
}
// std::vector:
int Node::getChannelListVecElement(int index) const
{
if (index < _channelList.size())
{
// index is valid.
return _channelList[index];
}
else
{
// index is invalid.
// Handle accordingly.
}
}
可以定義爲使用上述構造整個事情一個setter。我建議首先使用std::fill()
擦除_channelList
的內容,然後將新陣列複製到_channelList
。您可以使用單元素吸氣劑作爲基礎,爲單個元素定義一個setter。
二傳手(整個事情):
// Array (either type):
// "CHANNEL_LIST_TYPE[N] channelList" is either "const int (&channelList)[N]" or
// "std::array<int, N>& channelList". Remember to replace it with the correct one in the
// actual code.
// Public function.
template<size_t N>
void Node::setChannelListArr(CHANNEL_LIST_TYPE[N] channelList)
{
setChannelListArr(std::integral_constant<bool, N <= _sz>{}, channelList);
}
// Private function, N <= _sz.
template<size_t N>
void Node::setChannelListArr(std::true_type x, CHANNEL_LIST_TYPE[N] channelList)
{
std::fill(std::begin(_channelList), std::end(_channelList), '\0');
std::copy(std::begin(channelList), std::end(channelList), std::begin(_channelList));
}
// Private function, N > _sz.
template<size_t N>
void Node::setChannelListArr(std::false_type x, CHANNEL_LIST_TYPE[N] channelList)
{
// channelList is too large. Handle appropriately.
}
// std::vector:
// "CHANNEL_LIST_TYPE[N]" is used as above, and should be replaced in your actual code.
// Also note that you can easily modify this function to accept another vector, by
// removing the template, making the parameter "const std::vector<int>& channelList", and
// using "channelList.size()" in place of "N" when calling resize().
template<size_t N>
void Node::setChannelListVec(CHANNEL_LIST_TYPE[N] channelList)
{
_channelList.resize(N); // Resize _channelList to have N elements.
std::fill(std::begin(_channelList), std::end(_channelList), '\0');
std::copy(std::begin(channelList), std::end(channelList), std::begin(_channelList));
}
二傳手(單件):
// Array (either type):
void Node::setChannelListArrElement(int index, int value)
{
if (index < _sz)
{
_channelList[index] = value;
}
else
{
// index is invalid. Handle accordingly.
}
}
// std::vector:
void Node::setChannelListVecElement(int index, int value)
{
if (index < _channelList.size())
{
_channelList[index] = value;
}
else
{
// index is invalid. Handle accordingly.
}
}
// Alternative std::vector setter:
void Node::setChannelListVecElement2(int index, int value)
{
if (index >= _channelList.size())
{
// index is out of bounds. Resize vector to fit it.
_channelList.resize(index + 1, '\0');
}
// Modify element.
_channelList[index] = value;
}
注意,這個答案假定channelList
是空值終止的,因爲它似乎是。如果channelList
是不是空終止,但你要停在第一個空元素填充_channelList
,那麼你就必須做一些更多的工作,有可能使用while
循環。
你可以找到大部分以上here的工作示例。這有點混亂,因爲它只是一個快速程序,我用它在輸入這個答案時測試各種東西。
[我對我可能錯過的任何錯誤和/或錯誤表示歉意。我相信我抓了他們,但可能仍然存在一些有]
[編輯:添加了一條說明如何使用固定大小的模板的構造與C數組。添加了C++ 11尾隨返回類型的方法,用於返回對數組的引用。添加了一個簡單的工作示例。] [編輯:爲向量添加了額外的單元素設置器。]
不要將數組作爲指針傳遞。就那麼簡單。 –
如果您需要固定大小的整數數組,請使用std :: array。如果你需要動態大小,請使用std :: vector 。不要打擾指針;通過(const)引用來傳遞它們。 –
也許你應該發佈你的C++代碼,以便我們可以看到你可能做錯了什麼。 –