我的工作的通用片(C ++ 11)代码的是应该与工作boost::multi_array
,Eigen::Matrix
和n维阵列中的,可能是其它类型的。在某些时候,我需要访问给定数组类型的元素类型。Boost数组包含一个称为typedef的数组Element
,而Eigen数组包含一个称为typedef的数组Scalar
。
我想要的是一种类型特征,它返回给定数组类型的元素类型。不幸的是,我不能仅仅针对所有可能的数组类型对特征类进行模板化处理,因为Eigen使用表达式模板,因此,存在无限多种类型的Eigen矩阵。因此,我将SFINAE与enable_if结合使用以实现我的特征。enable_if应该选择的标准是,一个类型的typedef是Element
还是Scalar
。
为此,我实现了type-traitshas_element
和has_scalar
,它们确定相应的typedef是否存在。我的实现受到此博客文章中有关类型要求的启发。
template <class T>
using ToVoid = void;
template <class T, class Enable = void>
struct has_scalar : public std::false_type {};
template <class T>
struct has_scalar<T, ToVoid<typename T::Scalar>> : public std::true_type {};
template <class T, class Enable = void>
struct has_element : public std::false_type {};
template <class T>
struct has_element<T, ToVoid<typename T::Element>> : public std::true_type {};
这样的想法是,false_type
如果未显示typedef ,则编译器将选择版本,而如果存在typedef ,则编译器将选择更专业的 true_type
版本。
获取标量类型的实际特征是这样实现的:
template <class Condition, class T = void>
using EnableIf = typename std::enable_if<Condition::value, T>::type;
template <class T, class Enable = void>
struct scalar_of;
template <class T>
struct scalar_of<T, EnableIf<has_element<T>>> {
using type = typename T::Element;
};
template <class T>
struct scalar_of<T, EnableIf<has_scalar<T>>> {
using type = typename T::Scalar;
};
template <class T>
using ScalarOf = typename scalar_of<T>::type;
一个简单的示例用例是这样的:
struct BoostArray {
using Element = double;
};
struct EigenArray {
using Scalar = float;
};
int main() {
using std::is_same;
assert((is_same<double, ScalarOf<BoostArray>>::value));
assert((is_same<float, ScalarOf<EigenArray>>::value));
}
现在,奇怪的是,这在Clang 3.4中也能正常工作。但是,GCC 4.8.1无法对此进行编译,并给出以下错误消息:
test.cpp: In substitution of ‘template<class T> using ScalarOf = typename scalar_of<T>::type [with T = BoostArray]’:
test.cpp:51:5: required from here
test.cpp:37:45: error: ambiguous class template instantiation for ‘struct scalar_of<BoostArray, void>’
using ScalarOf = typename scalar_of<T>::type;
^
test.cpp:27:8: error: candidates are: struct scalar_of<T, typename std::enable_if<has_element<T, void>::value, void>::type>
struct scalar_of<T, EnableIf<has_element<T>>> {
^
test.cpp:32:8: error: struct scalar_of<T, typename std::enable_if<has_scalar<T, void>::value, void>::type>
struct scalar_of<T, EnableIf<has_scalar<T>>> {
lang版本在这里并且可以正常工作。gcc版本在这里,无法编译。
我的问题:我的代码是否正确,这是GCC 4.8.1的问题;还是我做错了什么,而Clang在编译时过于慷慨?无论如何,如何更改我的代码以使GCC 4.8.1可以对其进行编译?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句