对于类型修改特征,我是否应该为 typename::transform<...>::type 提供一个模板 typedef(又名使用)方便包装器?
For type modification traits, should I provide a template-typedef (aka using) convenience wrapper for typename::transform<...>::type?
我想知道有了模板类型的可用性,我应该为转换类型的类提供方便的包装器。考虑这个(无用的)示例:
template< T >
struct whatever
{
typedef typename std::conditional< sizeof(T) <= sizeof(void*),
int, long >::type type;
};
这里的, std::conditional
是标题中的transform
,与typename transform<...>::type
一起使用。此外,whatever
本身也是transform
,并且以相同的方式使用。
using
),我可以将接口更改为:
template< T >
using whatever = typename std::conditional< sizeof(T) <= sizeof(void*),
int, long >::type;
简化了用法。对于所有这些情况都可以这样做,但是由于需要(部分)专门化,您有时会最终使用实现类和包装器。在std::conditional
的情况下,您可能最终将其移动到std::impl::conditional<...>
,并提供另一个包装器
namespace std
{
namespace impl
{
// "classic" implementation of std::conditional
}
template< bool B, typename T, typename F >
using conditional = typename impl::conditional< B, T, F >::type;
}
这留下了我应该提供什么接口/API的问题。我看到提供包装器的一个优点:它可以防止用户错误。例如这个问题&答案。为了保持现有的接口,我看到了以下几点:
- 一致性。这就是类型特征基本上每个人都在使用
- 变压器与变换结果的分离。您可以将转换器作为类型传递,在上面的
whatever
的情况下,这将不再是可能的。 - 通过防止专门化所需的
impl
解决方案减少代码。
我想听到支持或反对提供"新"接口的争论,而不仅仅是"我更喜欢第二种方法"这样的意见。我感兴趣的是找出需要一种或另一种方法的情况,或者当它无法工作/扩展时。
老实说,这个问题主要是我缺乏模板类型的经验,所以如果你有一些实际的经验,请分享它的好和坏的一面,以及我是否应该认为typename transform<...>::type
API在c++ 11中已经过时了
我总是这样做:
- 在一些命名空间(impl, detail等)中有做实际工作的类。
- 外部,使用模板别名来清理调用代码。
例如,如果我要重写std::remove_reference,我会这样做:
namespace detail {
template <typename T> struct remove_reference
{
using type = T;
};
template <typename T> struct remove_reference<T&>
{
using type = T;
};
template <typename T> struct remove_reference<T&&>
{
using type = T;
};
}
template <typename T>
using remove_reference = typename detail::remove_reference<T>::type;
我没有编译上面的代码,所以如果我打错了,请不要射我。
一个好处是调用地点更加清晰。一个潜在的缺点是,如果你正在编写高阶泛型代码,并且依赖于某些类型函数(例如
)内部存在的::类型。template <template <typename...> class F, typename... Ts>
using apply = typename F<Ts...>::type;
不过你可以把using行改成
using apply = F<Ts...>;
没有任何伤害。这一切都归结于代码的其余部分在做什么。如果你的类型函数需要有一个特定的接口(::type或::value),那么你需要遵守它们。
相关文章:
- 如何在c++17中制作一个模板包装器/装饰器
- 将 N-arg 函数包装到另一个函数中
- 包装一个对象并假装它是一个 int
- 如何包装一个函数以适应另一个函数的所需类型
- 包装器是从 strcat_s() 到 strcat() 吗?如果没有,是否可以创建一个?
- 如何将 c++ 类包装到 python 中,以便我可以使用 pybind11 访问其成员的公共方法(成员是一个对象指针)
- 用输出参数包装一个c++函数,以便在javascript/node中使用
- PYBIND11:如何将C 和Python代码包装到一个包装中
- c++11:如何编写一个包装函数来生成"std::function"对象
- OpenCv c++为基本的打印垫函数创建一个c包装器
- Objective-C - 为C++函数创建一个包装器文件
- 用我自己的例外编写一个包装器
- 围绕可以通过C链接器链接的C++库创建一个C包装器
- 如何在Cython中从另一个包装对象返回包装的c++对象
- 如何编写一个包装器,使其保持对输出的跟踪
- 为ActiveMQ制作一个包装器类
- 我如何在c#上为一个包装的c++方法写一个签名,该方法的参数中有一个指向函数的指针
- 为std算法函数创建一个包装器,用容器代替迭代器
- 我可以为任何c++向量做一个C包装器吗?
- 如何为delete编写一个C包装器,既快速又释放给定的任何类型,而不告诉它是什么类型