Fhiclcpp types in detail » History » Version 19

« Previous - Version 19/56 (diff) - Next » - Current version
Kyle Knoepfel, 09/02/2015 03:21 PM

fhiclcpp types in detail

Parameter constructors

General rules

For each of the fhiclcpp types, the following rules apply:
  • The Name argument is required.
  • If there is more than one argument, the Name argument must be first in the list.
  • If there are three arguments, the relative order of the Comment argument and default-value argument is not important.
    Atom<int> val { Name("val"), Comment("Some parameter"), 9 }; // is equivalent to
    Atom<int> val { Name("val"), 9, Comment("Some parameter") };
  • The Table<T> parameter does not support a default value.


Atom<int> var { Name("var") };
Atom<int> var { Name("var"), 9 };
Atom<int> var { Name("var"), Comment("A parameter description") };
Atom<int> var { Name("var"), Comment("A parameter description"), 9 };


This class template is used for unbounded sequences. See the two caveats below.

Sequence<int> seq { Name("seq") };
Sequence<int> seq { Name("seq"), Comment("A sequence") };
Sequence<int> seq { Name("seq"), Sequence<int>{ 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), { 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), Comment("A sequence"), Sequence<int>{ 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), Comment("A sequence"), { 4, 5, 6, 7 } };


Due to the implementation details of the unbounded sequence, the following:

Sequence<int> seq { Name("seq"), Sequence<int>{} }; // Don't do this.

does not represent an empty sequence. If you would like an empty sequence as a default value, use the following:

Sequence<int> seq { Name("seq"), Sequence<int>::make_empty() };

Precaution regarding narrowing conversions and std::initializer_list objects

The following configuration will trigger a compilation warning:

Sequence<int> seq1 { Name("seq1"), Sequence<int>{ 1, 2.4e-4 } };
Sequence<int> seq2 { Name("seq2"), { 1, 2.4e-4 } };

that looks similar to this:

warning: narrowing conversion of ‘2.4000000000000001e-4’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]

For build systems that convert compile-time warnings to errors, this will result in a build failure. The warning results from the nature of an std::initializer_list object, signified by '{1, 2.4e-4}', which is used to initialize the sequence objects. For std::initializer_list objects, narrowing conversions are not allowed--that is, converting a double to an int is an example of narrowing that results in loss of information. This is the most likely example of where you may find a narrowing conversion.


This class template is used for sequences of a specific length, known at compile time.

Sequence<int,3u> seq { Name("seq") };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence") };
Sequence<int,3u> seq { Name("seq"), Sequence<int,3u>{ 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), { 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence"), Sequence<int,3u>{ 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence"), { 4, 5, 6 } };

The warning regarding narrowing conversions above applies for bounded sequences as well.


Tuple<string,bool> tuple { Name("tuple") };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple") };
Tuple<string,bool> tuple { Name("tuple"), Tuple<string,bool>{"explicit?", true} };
Tuple<string,bool> tuple { Name("tuple"), {"compact?", true } };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple"), Tuple<string,bool>{ "Particle physics is neat.", true } };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple"), { "This is false", false } };


Table<T> config { Name("config") };
Table<T> config { Name("config"), Comment("This describes the table") };

Return types

fhiclcpp parameter Function call Return type
Simple fhiclcpp parameters
Atom<std::string> label; label() std::string const&
Sequence<int> counts; counts() std::vector<int>
counts(1) int
Sequence<double, 3u> point; point() std::array<double, 3u>
point(0) double
Tuple<std::string, double> assoc; assoc() std::tuple<std::string, double>
assoc.get<0>() std::string
assoc.get<double>() double
Table<Config> config; config() Config const&
Nested fhiclcpp parameters
Sequence< Sequence<int> > datasets; datasets() std::vector< std::vector<int> >
datasets(17) std::vector<int>
Sequence< Sequence<int>, 2u > twoDatasets; twoDatasets() std::array< std::vector<int>, 2u >
twoDatasets(1) std::vector<int>
Sequence< Sequence<int, 2u> > intPairs; intPairs() std::vector< std::array<int, 2u> >
intPairs(42) std::array<int, 2u>
Sequence< Tuple<std::string, int, bool> > triplets; triplets() std::vector< std::tuple<std::string, int, bool> >
triplets(3) std::tuple<std::string, int, bool>
Sequence< Table<Config> > manyConfigTables; manyConfigTables() std::vector< Config >
manyConfigTables(6) Config const&
Tuple< std::string, Table<Config> > configAssoc; configAssoc() std::tuple< std::string, Config >
configAssoc.get<0>() std::string
configAssoc.get<std::string>() std::string
configAssoc.get<1>() Config
configAssoc.get< Table<Config> >() Config
Tuple< Tuple<std::string,bool>, Sequence<int> > awkward; awkward() std::tuple< std::tuple<std::string, bool>, std::vector<int> >
awkward.get<0>() std::tuple<std::string,bool>
awkward.get<1>() std::vector<int>

Common parameter accessors

Each of the fhiclcpp types has the following accessors:

std::string key()            const;
std::string comment()        const;
bool        has_default()    const;
par_type    parameter_type() const;

To call these functions, the difference in syntax is crucial:

Atom<int> val { Name("val") };

auto key1 = val.key();   //   correct
auto key2 = val().key(); // ! compile-time ERROR - 'val()' is an int, which has no accessor called 'key()' 


A call to key() returns the full key, including all enclosing tables. For example, consider a module that is designed to allow the following configuration:

pset: {
  list: [ { particle: electron },
          { particle: muon } ]
For a suitably declared set of fhiclcpp parameters, the returned key corresponding to "muon" would be pset.list[1].particle.

N.B. The returned value is different than the relative name that is supplied in the Name("val") argument to the fhiclcpp parameter constructor.

[ The following three functions are used primarily by the validation/description system. Although they are not likely to be directly helpful for the user, the user is still permitted to call them. ]


Returns the comment supplied as the string literal in (e.g.) Comment("Here is the comment"). If no Comment argument is provided in the fhiclcpp parameter constructor, a call to this function returns an empty string.


Returns true or false depending on whether the user supplied a default value for the parameter.


Returns an enumeration value based on the parameter type:

enum class par_type {
  ATOM,        // Atom<T>
  TABLE,       // Table<T>
  SEQ_VECTOR,  // Sequence<T>
  SEQ_ARRAY,   // Sequence<T,std::size_t>
  TUPLE,       // Tuple<T...>
  NTYPES       // Signifies invalid parameter