5

I am trying to make this code compile in VS 2019 (16.10.4) with /std:c++17. The following fails:

namespace my
{
   template<class _Key, class _Compare = std::less<_Key>, class _Allocator = std::allocator<_Key>>
   using Set = std::set<_Key, _Compare, _Allocator>;
}

void test()
{
    std::set set1 = { 1, 2, 3 };
    static_assert(std::is_same_v<std::set<int>, decltype(set1)>);

    my::Set set2 = { 1, 2, 3 }; // Error here.
    static_assert(std::is_same_v<my::Set<int>, decltype(set2)>);
}

with error:

error C2955: 'my::Set': use of alias template requires template argument list
message : see declaration of 'my::Set'

The same code compiles fine on godbolt with gcc -std=c++17 without any deduction guides. See sample.

Is there a way to make this compile on VS 2019 (16.10.4) with /std:c++17? My actual code is quite verbose. I created this minimal reproducible sample and it might just come down to solving this small piece. I also tried specifying deduction guides for my::Set but they have similar errors.

Fedor
  • 17,146
  • 13
  • 40
  • 131
Rahul Bhobe
  • 4,165
  • 4
  • 17
  • 32
  • Similar error with clang : `alias template 'Set' requires template arguments; argument deduction only allowed for class templates`. `"Alias templates are never deduced"` - https://en.cppreference.com/w/cpp/language/template_argument_deduction. Don't know why gcc allows it. – Staz Aug 13 '21 at 08:41
  • *"Is there a way to make this compile on VS 2019"...*: Looks like GCC is buggy. Making the `Set` to a class will work for both clang and MSVS: https://gcc.godbolt.org/z/vTr4sedx4 – JeJo Aug 13 '21 at 09:06
  • You should not do that as it make code harder to understand as almost every one knows what `std::set`is but only you know about `my::Set`. And if you want aliases, then it should be for a specific cases. Also it is **not a good idea to have a set of floating points** as you can easily run into problems because of rounding issues. – Phil1970 Aug 13 '21 at 13:15
  • It got the same error with `gcc9.4`. Built ok with `VS (16.11) /std:c++20` – nhatnq Aug 13 '21 at 13:44
  • @Phil1970 Good point about the float. I updated my samples in the question. This is just a minimal reproducible sample code. And in reality I am neither using `std::set`, nor `float`. – Rahul Bhobe Aug 13 '21 at 14:48
  • 2
    Deduction guides for template aliases is a C++20 feature. [More details in this answer](https://stackoverflow.com/questions/41008092/class-template-argument-deduction-not-working-with-alias-template). – Raymond Chen Aug 14 '21 at 10:20
  • It compiles fine under latest VS if in c++20 mode. As this I expect current gcc is buggy in the sense that it applies newer features even if older standard is selected. That kind of "bug" is seen very very often and typically will never fixed. – Klaus Dec 29 '21 at 12:53

1 Answers1

0

my::Set in your code is an alias template, and class template argument deduction for alias templates is a new feature of C++20: https://en.cppreference.com/w/cpp/compiler_support/20

Experimentally one can find that template argument deduction in this example is available in Visual Studio since version 16.11, please also specify /std:c++20 command-line option. Demo: https://gcc.godbolt.org/z/93jdvfPcn

The same code compiles fine on godbolt with gcc -std=c++17 without any deduction guides.

It is a bug in GCC that it allows class template argument deduction for alias templates in C++17 mode: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103852

Fedor
  • 17,146
  • 13
  • 40
  • 131