0

Recently I was using concepts to define different constructors for a templated class. Here is the code:

#include <iostream>
#include <concepts>

template<typename T> concept scalar = std::is_scalar_v<T>;

template<typename T>
class Foo
{
public:
    Foo(T t) requires scalar<T>: _t{t} { std::cout << "is scalar" << std::endl; }
    Foo(T t) requires (not scalar<T>): _t{t} { std::cout << "is not scalar" << std::endl;}
private:
    T _t;
};

class cls {};

int main() 
{
    Foo(true);
    Foo('d');
    Foo(3.14159);
    cls c;
    Foo(c);

    return 0;
}

To my surprise the code does not compile using GCC (trunk). The first part of the error message reads:

error: conflicting declaration 'Foo<...auto...> c'

What do you think, is it a bug or a feature?

T.C.
  • 129,563
  • 16
  • 274
  • 404
BlueTune
  • 905
  • 4
  • 14

1 Answers1

1

It looks like an issue with parenthesis and the expression being a constructor call without anything else (maybe a most vexing parse kind-of situation?).

These compile:

auto fc = Foo(c);
Foo{c};
Foo(cls{});
Foo<cls>({});
bolov
  • 65,999
  • 14
  • 127
  • 202