为什么模板 class 会有未使用的类型?
Why would a template class have an unused type?
我正在查看 boost units 库,我很困惑为什么 boost::units::unit class 有一个额外的模板参数。这是示例:
http://www.boost.org/doc/libs/1_57_0/boost/units/unit.hpp
template<class Dim,class System, class Enable>
class unit
{
public:
typedef unit<Dim, System> unit_type;
typedef unit<Dim,System> this_type;
typedef Dim dimension_type;
typedef System system_type;
unit() { }
unit(const this_type&) { }
//~unit() { }
this_type& operator=(const this_type&) { return *this; }
// sun will ignore errors resulting from templates
// instantiated in the return type of a function.
// Make sure that we get an error anyway by putting.
// the check in the destructor.
#ifdef __SUNPRO_CC
~unit() {
BOOST_MPL_ASSERT((detail::check_system<System, Dim>));
BOOST_MPL_ASSERT((is_dimension_list<Dim>));
}
#else
private:
BOOST_MPL_ASSERT((detail::check_system<System, Dim>));
BOOST_MPL_ASSERT((is_dimension_list<Dim>));
#endif
};
class用于向维度系统添加维度。
typedef unit<pressure_dimension,si::system> pressure;
在这种情况下 "Enable" 有什么作用?
class 模板是 forward declared in "units_fwd.hpp"
。
template<class Dim,class System, class Enable=void> class unit;
我们看到第三个参数默认为 void
。我什至想做 template<class Dim,class System, class=void> class unit;
并在实现中不命名,但可能存在编译器兼容性或代码标准,这意味着它们将其命名为 Enable
.
这样的 "extra" 类型允许对前两种类型进行 SFINAE 测试。如果您创建一个特化,其中第三种类型仅对 Dim
和 System
的某些子集有效,则额外参数(默认为 void
)允许您这样做。
您甚至可以将基本实现留空(;
或 {};
,它们具有不同的效果)并且仅专门化,使测试失败的参数被视为无效选项。
这是 SFINAE 的玩具示例:
template<class T, class=void> struct is_int : std::false_type {};
template<class T> struct is_int< T,
std::enable_if_t< std::is_same<T, int>{} >
> : std::true_type {};
基础专业继承自 false_type
。但是,如果 T
类型在下一个特化中通过了我的测试,它是首选,并且结果继承自 true_type
.
在这种情况下,我们只做 is_int< int, void >:std::true_type{}
会更好,但在更复杂的情况下(比如 is_integral
),我们可以进行几乎任意的编译时检查,并且用它来启用或禁用 [=23=] 专业化。
我正在查看 boost units 库,我很困惑为什么 boost::units::unit class 有一个额外的模板参数。这是示例:
http://www.boost.org/doc/libs/1_57_0/boost/units/unit.hpp
template<class Dim,class System, class Enable>
class unit
{
public:
typedef unit<Dim, System> unit_type;
typedef unit<Dim,System> this_type;
typedef Dim dimension_type;
typedef System system_type;
unit() { }
unit(const this_type&) { }
//~unit() { }
this_type& operator=(const this_type&) { return *this; }
// sun will ignore errors resulting from templates
// instantiated in the return type of a function.
// Make sure that we get an error anyway by putting.
// the check in the destructor.
#ifdef __SUNPRO_CC
~unit() {
BOOST_MPL_ASSERT((detail::check_system<System, Dim>));
BOOST_MPL_ASSERT((is_dimension_list<Dim>));
}
#else
private:
BOOST_MPL_ASSERT((detail::check_system<System, Dim>));
BOOST_MPL_ASSERT((is_dimension_list<Dim>));
#endif
};
class用于向维度系统添加维度。
typedef unit<pressure_dimension,si::system> pressure;
在这种情况下 "Enable" 有什么作用?
class 模板是 forward declared in "units_fwd.hpp"
。
template<class Dim,class System, class Enable=void> class unit;
我们看到第三个参数默认为 void
。我什至想做 template<class Dim,class System, class=void> class unit;
并在实现中不命名,但可能存在编译器兼容性或代码标准,这意味着它们将其命名为 Enable
.
这样的 "extra" 类型允许对前两种类型进行 SFINAE 测试。如果您创建一个特化,其中第三种类型仅对 Dim
和 System
的某些子集有效,则额外参数(默认为 void
)允许您这样做。
您甚至可以将基本实现留空(;
或 {};
,它们具有不同的效果)并且仅专门化,使测试失败的参数被视为无效选项。
这是 SFINAE 的玩具示例:
template<class T, class=void> struct is_int : std::false_type {};
template<class T> struct is_int< T,
std::enable_if_t< std::is_same<T, int>{} >
> : std::true_type {};
基础专业继承自 false_type
。但是,如果 T
类型在下一个特化中通过了我的测试,它是首选,并且结果继承自 true_type
.
在这种情况下,我们只做 is_int< int, void >:std::true_type{}
会更好,但在更复杂的情况下(比如 is_integral
),我们可以进行几乎任意的编译时检查,并且用它来启用或禁用 [=23=] 专业化。