Index: boost/parameter/aux_/arg_list.hpp =================================================================== --- boost/parameter/aux_/arg_list.hpp (révision 82663) +++ boost/parameter/aux_/arg_list.hpp (copie de travail) @@ -25,6 +25,7 @@ #include #include #include +#include namespace boost { namespace parameter { @@ -187,6 +188,29 @@ , typename TaggedArg::value_type >::type value_type; +private: + // This metafunction is used to make a type dependent on a template + // parameter. This is required below to delay the instantiation of the + // return type of functions. + // Since `arg_list` is used for named template parameters, the `reference` + // type can't always be expected to be a type valid as a return type + // (it could legitimately be a function type or an array type). Unless + // delayed, the function signatures are instantiated even when the + // functions are not actually used (in the case of named template + // parameters) because of how the `arg_list` is implemented; by means + // of inheritance from `Next`. + // + // Note: In the code below, we sometimes use enable_if with is_same + // when the signature is not really dependent on anything but + // we still need to introduce a template parameter to have a + // dependent return type. + template + struct make_dependent_on { + typedef Type type; + }; + +public: + TaggedArg arg; // Stores the argument // Store the arguments in successive nodes of this list @@ -255,13 +279,15 @@ // Helpers that handle the case when TaggedArg is // empty. template - reference get_default(D const&, mpl::false_) const + typename make_dependent_on::type + get_default(D const&, mpl::false_) const { return arg.value; } template - reference get_default(D const& d, mpl::true_) const + typename make_dependent_on::type + get_default(D const& d, mpl::true_) const { return arg.value ? arg.value.get() : arg.value.construct(d.value); } @@ -323,40 +349,53 @@ // reached, indicating no matching argument was passed, the // default is returned, or if no default_ or lazy_default was // passed, compilation fails. - reference get(keyword const&) const + + // Note: See the comment @make_dependent_on to know the rationale behind + // the use of enable_if with is_same instead of a straight overload. + template + typename enable_if, + reference>::type get(keyword const&) const { BOOST_MPL_ASSERT_NOT((holds_maybe)); return arg.value; } template - reference get(default_ const& d) const + typename make_dependent_on::type + get(default_ const& d) const { return get_default(d, holds_maybe()); } template - reference get(lazy_default) const + typename make_dependent_on::type + get(lazy_default) const { return arg.value; } #else - reference operator[](keyword const&) const + // Note: See the comment @make_dependent_on to know the rationale behind + // the use of enable_if with is_same instead of a straight overload. + template + typename enable_if, + reference>::type operator[](keyword const&) const { BOOST_MPL_ASSERT_NOT((holds_maybe)); return arg.value; } template - reference operator[](default_ const& d) const + typename make_dependent_on::type + operator[](default_ const& d) const { return get_default(d, holds_maybe()); } template - reference operator[](lazy_default) const + typename make_dependent_on::type + operator[](lazy_default) const { return arg.value; }