It seems to me that your looking a struct with an (declared only) operator T () for a generic T
struct generic_argument
{
template <typename T>
operator T () const;
};
so you can pass it (inside a decltype()) for every expected argument and also a template argument.
So your concept (sorry... I simplify it removing the ranges argument) become (if I understand what do you want) something as
template<typename T>
concept Foo
= std::convertible_to<decltype(std::declval<T>().func(std::declval<generic_argument>())),
double>;
The following is a full compiling example
#include <iostream>
struct A { double func (int a) { return a; } };
struct B { double not_func (long a) { return a; } };
struct C { std::string func (char) { return "abc"; } };
struct D { float func (auto) { return 1.0f; } };
struct E { double func (int a) { return a; }
std::string func (char) { return "abc"; } };
struct generic_argument
{
template <typename T>
operator T () const;
};
template<typename T>
concept Foo
= std::convertible_to<decltype(std::declval<T>().func(std::declval<generic_argument>())),
double>;
template <Foo T>
void bar (T const &)
{ std::cout << "bar, Foo version\n"; }
template <typename T>
void bar (T const &)
{ std::cout << "bar, generic version\n"; }
int main()
{
bar(A{}); // print bar, Foo version
bar(B{}); // print bar, generic version [no func() function]
bar(C{}); // print bar, generic version [no convertible to double]
bar(D{}); // print bar, Foo version
bar(E{}); // print bar, generic version [two func() function]
}
I'm in doubt regarding the E case: two func() methods, one only return a type convertible to double, from bar(E{}) we get "bar, generic version".