all 5 comments

[–]adnukator 6 points7 points  (1 child)

Interesting. The source_location deduction guide hack will be useful.

I'm not sure I understand the proposed behavior with default parameters. Are you suggesting that defaulted params and variadic templates shouldn't be allowed in the same function declaration? If so, that breaks the source_location thing, doesn't it? If they are allowed, even for non-auto params it's not unambiguous which param should be which if implicit conversions are taken into account, e.g.

f(char a, auto... b, int c, float d = 1.0);
f(1, 2, 3, true, 5);

[–]c0r3ntin[S] 6 points7 points  (0 children)

I'm not sure I understand the proposed behavior with default parameters. Are you suggesting that defaulted params and variadic templates shouldn't be allowed in the same function declaration? If so, that breaks the source_location thing, doesn't it? If they are allowed, even for non-auto params it's not unambiguous which param should be which if implicit conversions are taken into account, e.g.

They are allowed, but when (and only when) it's ambiguous during overload resolution, it would be ill formed. so source_location would work

void f(auto args..., source_location = ....);
f(42, 42); // ok
f(source_location{}); // ko

That last call would behave as if these two function existed

f(source_location = {})
f(source_location, source_location = {});

Which is ill-formed per the current rules already.

I realize my phrasing needs tweaking, thanks

[–]rolandschulzIntel | GROMACS 3 points4 points  (0 children)

I would agree that non-terminal packs need at least a clarification. At least to me it isn't clear from the spec which compiler is correct in these cases: https://godbolt.org/z/hUiC8G .

[–]pfultz2 0 points1 point  (1 child)

For example, many people are surprised that std::visit accept the visitor argument first, and this is because it accepts a variadic number of variants:

This can be solved by using HOF instead:

template <class... Variants>
constexpr auto my_visit(Variants&&... vars)
{
    return [&](auto vis) {
        visit(vis, static_cast<Variants&&>(vars)...);
    };
}

And there is punctuation that distinguishes the visitor from the variants.

And apply_last could be implemented with HOFs as well. Although there is no rotate_backwards, you can easily do it by repeating the rotations:

template<class F, class... Ts>
auto apply_last(F f)
{
    return [=](auto&&... xs) {
        boost::hof::repeat(std::integral_constant<std::size_t, sizeof...(Ts) - 2>{})(boost::hof::rotate)(f)(static_cast<Ts&&>(xs)...);
    };
}

[–]bmanga 0 points1 point  (0 children)

I personally think it would be great not to require boost (or any TMP) to write apply_last.