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.
  • 133,968
  • 17
  • 288
  • 421
BlueTune
  • 1,023
  • 6
  • 18

1 Answers1

2

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
  • 72,283
  • 15
  • 145
  • 224