Bug 66841 - [concepts] bogus error "invalid reference to function concept" when function concept is overloaded
Summary: [concepts] bogus error "invalid reference to function concept" when function ...
Status: RESOLVED DUPLICATE of bug 66834
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: c++-concepts
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-07-11 18:17 UTC by Eric Niebler
Modified: 2015-08-04 13:37 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Niebler 2015-07-11 18:17:35 UTC
This is related to the discussion in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66834. Because of the kind mismatch error described in 66834, the straightforward implementation of Constructible doesn't work, and the concept must be overloaded. But once it's overloaded, uses of it cause of "invalid reference to function concept" error.


template <class T, class U>
concept bool Same =
  __is_same_as(T, U);

template <class T, class U>
concept bool ExplicitlyConvertible() { return
  Same<T, U> ||
  requires(T&& t) {
    static_cast<U>((T&&)t);
  };
}

template <class T>
concept bool Constructible() { return
  requires {
    T{ };
  };
}

template <class T, class U>
concept bool Constructible() { return
  ExplicitlyConvertible<U, T>() ||
  requires (U&& u) {
    T{ (U&&)u };
  };
}

template <class T, class U, class V, class...Args>
concept bool Constructible() { return
  requires (U&& u, V&& v, Args&&...args) {
    T{ (U&&)u, (V&&)v, (Args&&)args... };
  };
}

template <class, class...>
constexpr bool core_constructible() { return false; }

template <class T, class...Args>
  requires Constructible<T, Args...>() // ERROR HERE
constexpr bool core_constructible() { return false; }


Yields:

../cmcstl2/scratch/constructible.cpp:40:23: error: invalid reference to function concept ‘template<class T, class U, class V, class ... Args> constexpr bool Constructible()’
 requires Constructible<T, Args...>()
                       ^
Comment 1 Andrew Sutton 2015-07-12 20:40:08 UTC
The program is ill-formed. In this line:

   requires Constructible<T, Args...>() // ERROR HERE

There's no single declaration of Constructible that can be matched to those template arguments. You would need one with this signature: <typename T, typename... Args>.

I think defining Constructible so that it backends into a type trait will give you the behavior you're looking for.

template<typename T, typename... Args>
concept bool Constructible() {
  return std::is_constructible<T, Args...>::value;
}
Comment 2 Eric Niebler 2015-07-12 20:44:33 UTC
This answer is deeply unsatisfying. I want valid expressions, not traits. And if std::is_constructible doesn't do *exactly* what I want (and it doesn't) I have to author my own trait, when what I want to do is author my own concept.

I'm not trying to do anything exotic here. There should be a way to do it without resorting to metaprogramming trickery and SFINAE.
Comment 3 Jason Merrill 2015-08-04 13:37:47 UTC
Let's keep the variadic concepts discussion in 66834.

*** This bug has been marked as a duplicate of bug 66834 ***