Is there a way to eliminate the code duplication?
Yes. The easy way is to provide only constructor taking the vector as argument (i.e. MyClass(std::vector<std::vector<float>> arg)
) and give an extra set of parenthesis to pass the vector list.
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!
{}
};
Now you can
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) };
See a Demo
However, if you insist to keep them both and have the common code, I would suggest a template member function which does this for you.
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));
}
};
Now you can write
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
See a Demo