Closed akrzemi1 closed 7 years ago
This changes the semantics of how require
works. By using a MF pointer, overloading require
no longer works, which is used for some traits in the library.
Also, tick uses type deduction to fill in the template types which seems more natural(at least to me). So if you write a trait like:
struct has_foo_r : tick::ops
{
template<class T>
auto require(const T& x) -> valid<
decltype(x.foo())
>;
};
It will work perfectly fine for has_foo<T>{}
and has_foo<const T>{}
. Using a MF pointer has_foo<const T>{}
will work, but has_foo<T>{}
will not, although I believe it should because it still meets the type requirements even if the const
is missing.
But for your case alternatively, you could use declval
:
struct has_f2_r : tick::ops
{
template<class T>
auto require(T&& x) -> valid<
decltype(x.f(std::declval<int>(), std::declval<int>()))
>;
};
Also, using default parameters should work as well:
struct has_f2_r : tick::ops
{
template<class T>
auto require(T&& x, int i = 0, int j = 0) -> valid<
decltype(x.f(i, j))
>;
};
Ok, thanks for the explanation. My primary motivation for testing Tick is to avoid using declval
everywhere. So option #1 will not work for me. Option #2 looks promising, but I do not know how it is going to scale to non-POD types.
The following program works fine (on GCC 7.2):
But I do not like it, because I am using literals 1 and 2 rather than saying "any
i
,j
of typeint
. So I change functionrequire
to:And now my concept stops working: it will always return
false
. The entire program:However, when I provide my own simplified implementation of
models
based on yours, it works again:So, I wonder, if this can be fixed in Tick?