我想要一个扩展的std::array
来表示数学向量(并且提供与array
相同的接口,无需样板代码)。我知道std::valarray
,但是我需要固定大小以便在矩阵乘法中进行正确类型转换。因此,array
非常适合。但是当我尝试继承构造函数时会失败。
struct vec2d : std::array<float, 2>
{ using array::array; }; // simplified
struct vec : std::vector<float>
{ using vector::vector; };
std::array<float, 2> x = {1, 2};
vec y = {1, 2};
vec2d z = {1, 2}; // error: could not convert ‘{1, 2}’
// from ‘<brace-enclosed initializer list>’ to ‘vec2d’
这个错误报告适用于GCC 4.8.2和clang 3.4。后者表示
vec2d
只有隐式默认/复制/移动构造函数。是的,array
只有与vector
相反具有隐式构造函数,不从initializer_list
构造。但由于构造函数是继承的,继承了用与array
初始化的同样的方式进行初始化是很自然的。
问题:为什么我们会遇到这个错误而不是期望的行为(类似于array
初始化)?
注意:我可以手动编写转发来使其正常工作,但这看起来不如构造函数继承优雅。struct vec2d : std::array<float, 2>
{
using array::array;
// nasty boilerplate code I don't want to have in C++11
template <typename... Args>
vec2d(Args &&... args) : array({float(std::forward<Args>(args))...}) {}
};
template<typename T, size_t N, size_t M> struct matrix { ... };
。但是为了实现您建议的内容,我必须进行2-3个特化,这些特化将具有不同的构造函数集,但是相同的成员集。template<typename T, size_t N> struct matrix<T, N, 1> : generic_matrix<T, N, 1> { matrix(array<T, N>); }
和template<typename T, size_t N, size_t M> struct matrix<T, N, M> : generic_matrix<T, N, M> { using generic_matrix };
。对我来说,引入额外的从array
到特殊情况的构造函数似乎是一种笨拙的解决方法,当M == 1
或N == 1
时使用。 - onystatic_assert
会产生相同的效果。虽然我非常反感sfinae,但我可能会错过一些东西。 - onystatic_assert
同样可以完成任务(并提供更好的错误消息)。然而,SFINAE可用于控制重载解析 - 您可以使用SFIANE使相同的客户端代码调用一个或另一个重载,而static_assert
无法提供此功能。 - Angew is no longer proud of SO