4

I'm writing a deduction guide in the style of an abbreviated function template, but I'm not sure if it's allowed. It compiles on gcc and clang, but not msvc.

The error is:

error C3539: a template-argument cannot be a type that contains 'auto'

Which compiler is doing the right thing?

try it out here

template <typename Type, int Count>
struct Array
{
    Type data[Count];

    Array (auto ... arg)
    {
        int count = 0;
        ((data[count++] = arg),...);
    }
};

// abbreviated function template syntax - fails in msvc
Array (auto first, auto ... next) -> Array<decltype(first), 1 + sizeof...(next)>;

// regular syntax
// template <typename Type, typename ... Args> Array (Type first, Args ... next) -> Array<Type, 1 + sizeof...(Args)>;

int main ()
{
    Array a(1,2,3);
}
1
  • It is pretty clear from MSDN documentation that msvc does not allow auto in parameters and template arguments in the default /Zc:auto mode. See C3533 and C3539 Commented Dec 14, 2022 at 19:27

1 Answer 1

4

According to [dcl.spec.auto.general]/6 any use of a placeholder type (e.g. auto) that is not explicitly permitted in [dcl.spec.auto] is not permitted.

And I don't see anything applying to deduction guides mentioned there. In particular [dcl.spec.auto.general]/2 which allows it in function parameters is explicitly limited to parameter-declarations in function declarations and lambda expressions.

So it does seem ill-formed to me.

However, I don't see any reason for this. I suspect that [dcl.spec.auto] and the definition of abbreviated function template in [dcl.fct] should just be extended to include parameter lists of deduction guides with analogues rules to match the statement in [temp.deduct.guide] that the parameter list of a deduction guide follows the same restrictions as that of a function declaration.

Sign up to request clarification or add additional context in comments.

2 Comments

Why would they want to encourage people to use this in places where you're definitely going to have to have a bunch of decltype(variable_name) instead of just using template? Broadly speaking, outside of lambdas, if you ever reach for decltype for an auto function parameter, you should stop and write a template header.
@NicolBolas I don't really think that is a good reason to add a non-obvious syntax difference to function/constructor declarations, when deduction guides mimic them. But even so in e.g. OP's example template<typename F> Array(F first, auto ... next) -> Array<F, 1 + sizeof...(next)>; wouldn't need a type name or decltype on next if the use of the placeholder was allowed. (Of course you may consider mixing the styles even worse, but there should be examples where no type name is used.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.