我有一个MyClass
类,目前看起来像这样:
class MyClass{
public:
MyClass(std::initializer_list<std::initializer_list<float>> arg){
// some code here
}
MyClass(vector<vector<float>> arg){
// identical code as above block
}
// other class members
};
可以使用MyClass
类型和std::initializer_list<std::initializer_list<float>>
类型来构造vector<vector<float>>
的实例,并且用于处理构造函数参数的代码块是相同的。有没有办法消除代码重复?
答案 0 :(得分:3)
是否有消除代码重复的方法?
是的。一种简单的方法是仅提供以向量为参数的构造函数(即MyClass(std::vector<std::vector<float>> arg)
),并提供额外的括号集以传递向量列表。
class MyClass
{
std::vector<std::vector<float>> mStorage;
public:
MyClass(std::vector<std::vector<float>> arg)
: mStorage{ std::move(arg) } // use member initializer lists here!
{}
};
现在您可以
MyClass obj1{ { {1.f, 2.f}, {3.f, 4.f} } }; // note the extra set of {}!
// and
auto vec2D = std::vector<std::vector<float>>{ {1.f, 2.f}, {3.f, 4.f} };
MyClass obj2{ std::move(vec2D) };
但是,如果您坚持保留两者并拥有通用代码,我建议您使用template member function来做到这一点。
class MyClass
{
std::vector<std::vector<float>> mStorage;
template<typename Type>
void setStorage(Type list) /* noexcept */
{
mStorage.assign(std::cbegin(list), std::cend(list));
}
public:
MyClass(const std::initializer_list<std::initializer_list<float>> arg) {
this->setStorage(arg);
}
MyClass(std::vector<std::vector<float>> arg) {
this->setStorage(std::move(arg));
}
};
现在您可以写
MyClass obj1{ {1.f, 2.f}, {3.f, 4.f} }; // uses std::initializer_list cont'r
// and
auto vec2D = std::vector<std::vector<float>>{ {1.f, 2.f}, {3.f, 4.f} };
MyClass obj2{ std::move(vec2D) }; // uses std::vector cont'r
答案 1 :(得分:2)
我的解决方案:
#include <iostream>
#include <vector>
class MyClass
{
public:
using Vec_vec = std::vector<std::vector<float>>;
MyClass(Vec_vec arg) : vv{std::move(arg)}
{
for (const auto& ilist : vv)
{
for (const auto& x : ilist)
{
s += x;
}
}
}
MyClass(std::initializer_list<std::vector<float>> arg) : MyClass(Vec_vec(arg.begin(), arg.end())) {}
Vec_vec vv;
float s {0};
};
int main()
{
std::vector<std::vector<float>> v = {{1, 2, 3}, {1, 2, 3}, {4}};
MyClass a{{1, 2, 3}, {2, 3, 4}, {5}};
MyClass b{v};
std::cout << a.s << " " << a.vv[0][0] << "\n"; // 1 + 2 + 3 + 2 + 3 + 4 + 5 = 20
std::cout << b.s << " " << b.vv[0][0] << "\n"; // 2*(1 + 2 + 3) + 4 = 16
}
注释,按代码中出现的顺序。
using
声明只是为了缩短表示法(并参数化代码)。与问题无关。std::move
。std::vector
的构造函数,该构造函数由两个迭代器定义的序列构造向量。该解决方案确实避免了重复代码args
等传递const reference
,我认为您比我更了解,因此这超出了问题的范围,但当然值得考虑。因此,此答案的读者不应将示例中的所有内容都视为“某些”。