【问题标题】:Avoiding Brackets for Class Template Having Default Parameter避免使用具有默认参数的类模板的括号
【发布时间】:2011-07-25 06:20:11
【问题描述】:

我有一个类似于下面的类模板,旨在包含解析 CSV 文件时使用的一些配置设置:

template <typename InputIterator = default_all>
class icsv_params
{
    // Iterator to a data structure containing the columns
    // that should be read.
    typedef InputIterator iterator;
    // This is a bitmask type.
    typedef detail::icsv_op icsv_op;

    static const icsv_op noqt = icsv_op(detail::csv_flags::noqt);
    static const icsv_op quot = icsv_op(detail::csv_flags::quot);
    static const icsv_op mmap = icsv_op(detail::csv_flags::mmap);

    // The rest of the class definition isn't relevant.
};

现在,当用户希望为包含应该解析的列数的数据结构提供开始和结束迭代器时,模板参数很重要;但是,如果用户未能将迭代器作为参数提供,该类应该自动假定所有列都应该被解析。

在第二种情况下,声明类实例的代码看起来很笨拙:

icsv_params<> params(...);

此外,位掩码类型noqtquotmmap 仅由此类使用,因此将它们放在类定义中是有意义的;但是,如果用户希望使用这些位掩码类型,那么执行此操作的代码也很笨拙:

icsv_params<> params(icsv_params<>::noqt);

我怎样才能使用户不需要提供尖括号来指示缺少模板参数?如果没有办法,您会建议什么替代方案?

【问题讨论】:

  • 函数模板不需要括号。假设 C++0x 那么用户代码可以做auto params = some_factory_function(...);.
  • 自 C++17 以来,情况发生了变化。现在你可以omit angle brackets

标签: c++ templates design-patterns


【解决方案1】:

不幸的是,这是 C++ 语法。 IIRC,在 C++0x 中,有关联的命名空间(这解决了你的第二个问题)。

对于第一个,typedef 应该做,à la STL:

template <typename InputIterator = default_all>
class basic_icsv_params
{
    ...
};

typedef basic_icsv_params<> icsv_params:

【讨论】:

  • 感谢您的回答!由于用户在提供模板参数时必须输入basic_ 前缀,这仍然让我感到不满意。到目前为止,只有 GCC 和 IMB C++ 支持这个特性 =(。希望这个特性能在其他主要编译器中快速实现。
  • @void-pointer:这就是标准库的作用。实际上,std::stringstd::basic_string&lt;Char = char, Traits = std::char_traits&lt;Char&gt;, Allocator = std::allocator&lt;Char&gt; &gt; 的 typedef。
【解决方案2】:

通常对于迭代器参数,迭代器类型是模板参数,仅用于需要它们的函数。例如,如果您查看 std::vector 构造函数,它使用 begin() 和 end() 迭代器进行模板化,但不是整个类型。

【讨论】:

  • OP 的类可能是某种特征类,因此可能确实需要迭代器类型作为模板参数。
  • 我想过这样做,但这是类定义的其余部分变得相关的地方:如果用户提供迭代器类型,那么类将需要存储该迭代器类型的实例,以便负责解析 CSV 文件的方法可以稍后检索它们。我可以通过这个限制吗?
【解决方案3】:

在我看来,实际上使用角括号是一种更好的方法。既然,他们不能被安排,替代方式可以是,

typedef icsv_params<> icsv_params_default;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 2019-01-09
    • 1970-01-01
    相关资源
    最近更新 更多