11

I have a class template similar to the one that follows below that is designed to contain some configuration settings used when parsing CSV files:

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.
};

Now, the template parameter is important when the user wishes to supply start and end iterators to a data structure containing the numbers of the columns that should be parsed; however, should the user fail to provide the iterators as parameters, the class should automatically assume that all of the columns should be parsed.

In the second case, the code to declare an instance of the class looks unwieldy:

icsv_params<> params(...);

Additionally, the bitmask types noqt, quot, and mmap are used by this class only, so it makes sense to put them inside the class definition; however, should the user wish to use these bitmask types, the code to do so is also unwieldy:

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

How can I make it so that the user does not need to provide the angle brackets to indicate the absence of a template parameter? If there is no way to do so, what alternative would you suggest?

void-pointer
  • 14,247
  • 11
  • 43
  • 61
  • 2
    Function templates don't need the brackets. Assuming C++0x then user code can do `auto params = some_factory_function(...);`. – Luc Danton Jul 25 '11 at 06:59
  • Since C++17 things have changed. Now you can [omit angle brackets](https://stackoverflow.com/a/55220221/3235496). – manlio Mar 18 '19 at 11:25

3 Answers3

5

Unfortunately this is C++ syntax. IIRC, in C++0x, there are associated namespaces (which solve your second question).

For the first one, a typedef should do, à la STL:

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

typedef basic_icsv_params<> icsv_params:
Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
  • Thanks for the answer! This still leaves an unsatisfied feeling in my stomach since the user will have to type the `basic_` prefix when providing the template parameter. So far, only GCC and IMB C++ support this feature =(. Hopefully this feature is implemented in other major compilers quickly. – void-pointer Jul 25 '11 at 06:42
  • 1
    @void-pointer: this is how the standard library does. Indeed, `std::string` is a typedef for `std::basic_string, Allocator = std::allocator >`. – Alexandre C. Jul 25 '11 at 08:26
0

Usually for iterator parameters, the iterator type is a template parameter to only the functions that need them. For example, if you look at the std::vector constructor, it's templated with begin() and end() iterators, but not the whole type.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • OP's class could be some kind of traits class and thus may really need the iterator type as a template parameter. – Alexandre C. Jul 25 '11 at 06:28
  • I thought about doing that, but this is where the rest of the class definition becomes relevant: should the user provide the iterator types, then the class will need to store instances of that iterator type so that the method that is responsible for parsing the CSV file can later retrieve them. Can I get by this limitation? – void-pointer Jul 25 '11 at 06:29
0

Putting angular braces in my opinion is a better way in fact. Since, they cannot be ingonred, Alternative way can be,

typedef icsv_params<> icsv_params_default;
iammilind
  • 68,093
  • 33
  • 169
  • 336