I have many derived classes from base. Those classes must inherit constructor from base, but that constructor should only work with derived or base class instances.
Base class example:
template<typename T, typename U>
struct bar
{
bar() = default;
template<typename _Bar_or_Derived>
bar(const _Bar_or_Derived &); // must accept any bar or its derived classes
};
Derived classes example:
template<typename T, typename U>
struct foo : public bar<T, U>
{
using bar<T, U>::bar;
// must inherit something like foo(const Foo_or_Bar&)
};
template<typename T, typename U>
struct not_foo : public bar<T, U>
{
using bar<T, U>::bar;
// must inherit something like not_foo(const NotFoo_or_Bar&)
};
How to do such a thing?
It seems you want CRTP instead of common base class to avoid to duplicate code:
template <typename > struct Bar;
template <template <typename, typename> class C, typename T1, typename T2>
struct Bar<C<T1, T2>>
{
Bar(const Bar&) {/*..*/}
template <typename U1, U2>
Bar(const Bar<C<U1, U2>>&) {/*..*/}
template <typename U1, U2>
Bar(const C<U1, U2>&) {/*..*/}
};
// Maybe you just need template <template <typename, typename> class C> struct Bar{};
// instead, as T1, T2 seems not used
template<typename T, typename U>
struct foo : public bar<foo>
{
using bar<foo>::bar;
};
template<typename T, typename U>
struct not_foo : public bar<not_foo>
{
using bar<not_foo>::bar;
};
How can I get a boolean value indicating if a known method has the const qualifier or not?
For example:
struct A {
void method() const {}
};
struct B {
void method() {}
};
bool testA = method_is_const<A::method>::value; // Should be true
bool testB = method_is_const<B::method>::value; // Should be false
In the type_traits header I found an is_const test I could use, but I need the method type, and I'm unsure how to obtain that.
I tried: std::is_const<decltype(&A::method)>::value but it doesn't work, and I can understand why (void (*ptr)() const) != const void (*ptr)()).
It is a lot simpler to check whether a member function can be called on a const-qualified lvalue.
template<class T>
using const_lvalue_callable_foo_t = decltype(std::declval<const T&>().foo());
template<class T>
using has_const_lvalue_callable_foo = std::experimental::is_detected<const_lvalue_callable_foo_t, T>;
Rinse and repeat, except with std::declval<const T>(), to check if said function can be called on a const-qualified rvalue. I can think of no good use cases for const && member functions, so whether there's a point in detecting this case is questionable.
Consult the current Library Fundamentals 2 TS working draft on how to implement is_detected.
It is a lot more convoluted to check whether a particular pointer-to-member-function type points to a function type with a particular cv-qualifier-seq. That requires 6 partial specializations per cv-qualifier-seq (const and const volatile are different cv-qualifier-seqs), and still can't handle overloaded member functions or member function templates. Sketching the idea:
template<class T>
struct is_pointer_to_const_member_function : std::false_type {};
template<class R, class T, class... Args>
struct is_pointer_to_const_member_function<R (T::*)(Args...) const> : std::true_type {};
template<class R, class T, class... Args>
struct is_pointer_to_const_member_function<R (T::*)(Args...) const &> : std::true_type {};
template<class R, class T, class... Args>
struct is_pointer_to_const_member_function<R (T::*)(Args...) const &&> : std::true_type {};
template<class R, class T, class... Args>
struct is_pointer_to_const_member_function<R (T::*)(Args..., ...) const> : std::true_type {};
template<class R, class T, class... Args>
struct is_pointer_to_const_member_function<R (T::*)(Args..., ...) const &> : std::true_type {};
template<class R, class T, class... Args>
struct is_pointer_to_const_member_function<R (T::*)(Args..., ...) const &&> : std::true_type {};
If you want const volatile to be true too, stamp out another 6 partial specializations along these lines.
The reason std::is_const<decltype(&A::method)>::value doesn't work is that a const member function isn't a const (member function). It's not a top-level const in the way that it would be for const int vs int.
What we can do instead is a type trait using void_t that tests whether we can call method on a const T:
template <typename... >
using void_t = void;
template <typename T, typename = void>
struct is_const_callable_method : std::false_type { };
template <typename T>
struct is_const_callable_method<T, void_t<
decltype(std::declval<const T&>().method())
> > : std::true_type { };
Demo
In C++20, things get a lot easier because concepts have been standardized, which subsumes the detection idiom.
Now all we need to write is this constraint:
template<class T>
concept ConstCallableMethod = requires(const T& _instance) {
{ _instance.method() }
};
ConstCallableMethod tests that the expression _instance.has_method() is well formed given that _instance is a const-reference type.
Given your two classes:
struct A {
void method() const { }
};
struct B {
void method() { }
};
The constraint will be true for A (ConstCallableMethod<A>) and false for B.
If you wish to also test that the return type of the method function is void, you can add ->void to the constraint like so:
template<class T>
concept ConstCallableMethodReturnsVoid = requires(const T& _instance) {
{ _instance.method() } -> void
};
If you wish to be a little more generic, you can pass in a member function pointer to the concept and test if that function pointer can be called with a const instance (although this gets a little less useful when you have overloads):
template<class T, class MemberF>
concept ConstCallableMemberReturnsVoid = requires(const T& _instance, MemberF _member_function) {
{ (_instance.*_member_function)() } -> void
};
You'd call it like so:
ConstCallableMemberReturnsVoid<A, decltype(&A::method)>
This allows for some other theoretical class like C, that has a const method, but it's not named method:
struct C
{
void foobar() const{}
};
And we can use the same concept to test:
ConstCallableMemberReturnsVoid<C, decltype(&C::foobar)>
Live Demo
Create a type trait to determine the const-ness of a method:
template<typename method_t>
struct is_const_method;
template<typename CClass, typename ReturnType, typename ...ArgType>
struct is_const_method< ReturnType (CClass::*)(ArgType...)>{
static constexpr bool value = false;
};
template<typename CClass, typename ReturnType, typename ...ArgType>
struct is_const_method< ReturnType (CClass::*)(ArgType) const>{
static constexpr bool value = true;
};
I have a class like this:
template <typename... Types>
class Evaluator
{
public:
template <typename... Types>
Evaluator(Types... args)
{
list = std::make_tuple(args...);
}
template <typename T>
bool Evaluate(const T& input)
{
// based on a specific input type T, here I want to call
// Evaluate(input) for a specific element in the tuple. i.e. the
// element that has method Evaluate, for which Evaluate(input) compiles
return std::get<0>(list).Evaluate(input);
}
private:
std::tuple<Types...> list;
};
Update The function could return false for instances that don't have proper "Evaluate(input) -> bool" function and is evaluated for all matching with bool result ||
Something like this:
// Unspecialized form, when the current element doesn't match. Tries the next one.
template <typename Tuple, int I, typename Argument, typename = void>
struct CallEvaluate : CallEvaluate<Tuple, I+1, Argument> {};
// Termination case, when the end of the tuple was reached. Has no operator () and will
// cause a compilation error.
template <typename Tuple, typename Argument>
struct CallEvaluate<Tuple, std::tuple_size<I>::value, Argument> {}; // no type fits
// Termination case, when the call std::get<I>(list).Evaluate(input) is valid.
template <typename Tuple, int I, typename Argument>
struct CallEvaluate<Tuple, I, Argument,
decltype(void(
std::declval<typename std::tuple_element<Tuple, I>::type>()
.Evaluate(std::declval<const Argument&>())))> {
bool operator ()(const Tuple& list, const Argument& input) const {
return std::get<I>(list).Evaluate(input);
}
};
// Use:
CallEvaluate<decltype(list), 0, T>()(list, input);
First of all, we need a metafunction which can tell us whether the expression declval<T>().Evaluate(input) makes sense for a given type T.
We can use SFINAE and decltype in order to do so:
template<class ... Arguments>
struct CanEvaluate
{
template<class T, class Enable = void>
struct eval : std::false_type {};
template<class T>
struct eval<T,
decltype( void( std::declval<T>().Evaluate(std::declval<Arguments>() ... ) ) ) > : std::true_type {};
};
Now we can write a single class MultiEvaluateFromTuple.
template<class TupleType, class ... InputTypes>
struct MultiEvaluateFromTuple
{
private:
template<int I,int S,class Dummy = void>
struct CheckEvaluate : CanEvaluate<InputTypes...>::template eval<typename std::tuple_element<I,TupleType>::type> {};
//We need this because we can't instantiate std::tuple_element<S,TupleType>
template<int S> struct CheckEvaluate<S,S> : std::false_type {};
// Forward to the next element
template<int I,int S, class Enabler = void>
struct Impl {
static bool eval(const TupleType & r, const InputTypes & ... input) {
return Impl<I+1,S>::eval(r,input...);
}
};
// Call T::Evalute()
template<int I,int S>
struct Impl<I,S, typename std::enable_if<CheckEvaluate<I,S>::value>::type> {
static bool eval(const TupleType & r, const InputTypes & ... input) {
bool Lhs = std::get<I>(r).Evaluate(input...);
bool Rhs = Impl<I+1,S>::eval(r,input...);
return Lhs || Rhs;
}
};
//! Termination
template<int S>
struct Impl<S,S> {
static bool eval(const TupleType & r, const InputTypes & ... input) {
return false;
}
};
public:
static bool eval(const TupleType & r,const InputTypes & ... input) {
return Impl<0, std::tuple_size<TupleType>::value>::eval(r,input...);
}
};
Usage:
return MultiEvaluateFromTuple<std::tuple<Types...>,T>::eval(list,input);
This will call Evaluate for all the types T in Types for which CanEvaluate<InputType>::eval<T>::value == true, and return the || of the results.
I'm not sure exactly what you're trying to do. Here's what I think is the solution:
template <typename... Types>
class Evaluator
{
private:
std::tuple<Types...> list;
template <typename T>
struct has_evaluator
{
typedef char yes;
typedef char no[2];
template <typename C, C>
struct S;
template <typename U>
yes& check(S<bool T::*, &T::Evaluate>*);
template <typename U>
no& check(...);
static const bool value = sizeof(check<T>(nullptr)) == sizeof(char);
};
public:
template <typename... Args>
Evaluator(Args&&... args) : list(std::make_tuple(std::forward<Args>(args)...))
{ }
template <typename T,
typename = typename std::enable_if<
has_evaluator<typename std::tuple_element<0, decltype(list)>::type>::value>::type>
auto Evaluate(const T& input) -> decltype(std::get<0>(list).Evaluate(input), bool())
{
return std::get<0>(list).Evaluate(input);
}
};
Is it possible to write a type trait, say is_callable<T> which tells if an object has an operator() defined?
It is easy if the arguments to the call operator are known in advance, but not in the general case.
I want the trait to return true if and only if there is at least one overloaded call operator defined.
This question is related and has a good answer, but it doesn't work on all types (only on int-convertible types). Also, std::is_function works, but only on proper C++ functions, not on functors. I'm looking for a more general solution.
I think this trait does what you want. It detects operator() with any kind of signature even if it's overloaded and also if it's templatized:
template<typename T>
struct is_callable {
private:
typedef char(&yes)[1];
typedef char(&no)[2];
struct Fallback { void operator()(); };
struct Derived : T, Fallback { };
template<typename U, U> struct Check;
template<typename>
static yes test(...);
template<typename C>
static no test(Check<void (Fallback::*)(), &C::operator()>*);
public:
static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
};
The principle is based on Member Detector idiom. As it is, it will fail to compile if you pass it a non-class type, but that shouldn't be hard to fix, I just left it out for brevity. You can also extend it to report true for functions.
Of course it doesn't give you any info about the signature(s) of operator() whatsoever, but I believe that's not what you asked for, right?
EDIT for Klaim:
It's simple enough to make it work (return false) with non-class types. If you rename the above class to is_callable_impl, you can write this, for example:
template<typename T>
struct is_callable
: std::conditional<
std::is_class<T>::value,
is_callable_impl<T>,
std::false_type
>::type
{ };
The answers here were helpful but I came here wanting something that could also spot whether something was callable regardless of whether it happened to be an object or a classic function. jrok's answer to this aspect of the problem, alas, didn't work because std::conditional actually evaluates the types of both arms!
So, here's a solution:
// Note that std::is_function says that pointers to functions
// and references to functions aren't functions, so we'll make our
// own is_function_t that pulls off any pointer/reference first.
template<typename T>
using remove_ref_t = typename std::remove_reference<T>::type;
template<typename T>
using remove_refptr_t = typename std::remove_pointer<remove_ref_t<T>>::type;
template<typename T>
using is_function_t = typename std::is_function<remove_refptr_t<T>>::type;
// We can't use std::conditional because it (apparently) must determine
// the types of both arms of the condition, so we do it directly.
// Non-objects are callable only if they are functions.
template<bool isObject, typename T>
struct is_callable_impl : public is_function_t<T> {};
// Objects are callable if they have an operator(). We use a method check
// to find out.
template<typename T>
struct is_callable_impl<true, T> {
private:
struct Fallback { void operator()(); };
struct Derived : T, Fallback { };
template<typename U, U> struct Check;
template<typename>
static std::true_type test(...);
template<typename C>
static std::false_type test(Check<void (Fallback::*)(), &C::operator()>*);
public:
typedef decltype(test<Derived>(nullptr)) type;
};
// Now we have our final version of is_callable_t. Again, we have to take
// care with references because std::is_class says "No" if we give it a
// reference to a class.
template<typename T>
using is_callable_t =
typename is_callable_impl<std::is_class<remove_ref_t<T>>::value,
remove_ref_t<T> >::type;
But in the end, for my application, I really wanted to just know whether you could say f() (i.e., call it with no arguments), so I instead went with something much simpler.
template <typename T>
constexpr bool noarg_callable_impl(
typename std::enable_if<bool(sizeof((std::declval<T>()(),0)))>::type*)
{
return true;
}
template<typename T>
constexpr bool noarg_callable_impl(...)
{
return false;
}
template<typename T>
constexpr bool is_noarg_callable()
{
return noarg_callable_impl<T>(nullptr);
}
In fact, I went even further. I knew the function was supposed to return an int, so rather than just check that I could call it, I checked the return type, too, by changing the enable_if to:
typename std::enable_if<std::is_convertible<decltype(std::declval<T>()()),
int>::value>::type*)
Hope this helps someone!
Here is a possible solution using C++11 that works without requiring to know the signature of the call operator for functors, but only as long the functor does not have more than one overload of operator ():
#include <type_traits>
template<typename T, typename = void>
struct is_callable : std::is_function<T> { };
template<typename T>
struct is_callable<T, typename std::enable_if<
std::is_same<decltype(void(&T::operator())), void>::value
>::type> : std::true_type { };
This is how you would use it:
struct C
{
void operator () () { }
};
struct NC { };
struct D
{
void operator () () { }
void operator () (int) { }
};
int main()
{
static_assert(is_callable<C>::value, "Error");
static_assert(is_callable<void()>::value, "Error");
auto l = [] () { };
static_assert(is_callable<decltype(l)>::value, "Error");
// Fires! (no operator())
static_assert(is_callable<NC>::value, "Error");
// Fires! (several overloads of operator ())
static_assert(is_callable<D>::value, "Error");
}
C++17 brings std::is_invocable and friends.
This answer also given a solution on how to emulate it with C++14.
There are several other answers already, of course, and they are useful, but none of them seem to cover every use case AFAICT. Borrowing from those answers and this possible implementation of std::is_function, I created a version that covers every possible use case of which I could think. It's kind of lengthy, but very feature complete (Demo).
template<typename T, typename U = void>
struct is_callable
{
static bool const constexpr value = std::conditional_t<
std::is_class<std::remove_reference_t<T>>::value,
is_callable<std::remove_reference_t<T>, int>, std::false_type>::value;
};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...), U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(*)(Args...), U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(&)(Args...), U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......), U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(*)(Args......), U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(&)(Args......), U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)const, U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)volatile, U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)const volatile, U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)const, U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)volatile, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)const volatile, U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)&, U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)const&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)volatile&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)const volatile&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)&, U> : std::true_type {};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)const&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)volatile&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)const volatile&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)&&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)const&&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)volatile&&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args...)const volatile&&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)&&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)const&&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)volatile&&, U> : std::true_type{};
template<typename T, typename U, typename ...Args>
struct is_callable<T(Args......)const volatile&&, U> : std::true_type{};
template<typename T>
struct is_callable<T, int>
{
private:
using YesType = char(&)[1];
using NoType = char(&)[2];
struct Fallback { void operator()(); };
struct Derived : T, Fallback {};
template<typename U, U>
struct Check;
template<typename>
static YesType Test(...);
template<typename C>
static NoType Test(Check<void (Fallback::*)(), &C::operator()>*);
public:
static bool const constexpr value = sizeof(Test<Derived>(0)) == sizeof(YesType);
};
This works correctly with non-class types (returns false, of course), function types (<T()>), function pointer types, function reference types, functor class types, bind expressions, lambda types, etc. This works correctly even if the class constructor is private and/or non-defaulted, and even if operator() is overloaded. This returns false for member function pointers by design because they are not callable, but you can use bind to create a callable expression.
Note: These assume that the default constructor is valid for the type your checking. Not sure offhand how to get around that.
The following seems to work if it's callable with 0 arguments. Is there something in is_function's implementation that might help to extend this to 1 or more argument callables?:
template <typename T>
struct is_callable {
// Types "yes" and "no" are guaranteed to have different sizes,
// specifically sizeof(yes) == 1 and sizeof(no) == 2.
typedef char yes[1];
typedef char no[2];
template <typename C>
static yes& test(decltype(C()())*);
template <typename>
static no& test(...);
// If the "sizeof" the result of calling test<T>(0) would be equal to the sizeof(yes),
// the first overload worked and T has a nested type named foobar.
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
If you know the type of the argument (even if it's a template parameter), the following would work for 1 argument, and I imagine one could extend pretty easily from there:
template <typename T, typename T2>
struct is_callable_1 {
// Types "yes" and "no" are guaranteed to have different sizes,
// specifically sizeof(yes) == 1 and sizeof(no) == 2.
typedef char yes[1];
typedef char no[2];
template <typename C>
static yes& test(decltype(C()(T2()))*);
template <typename, typename>
static no& test(...);
// If the "sizeof" the result of calling test<T>(0) would be equal to the sizeof(yes),
// the first overload worked and T has a nested type named foobar.
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
Edit
here is a modification that handles the case where default constructor isn't available.
This is a neat and short trick for finding if T is callable. It goes along the lines originally proposed by Walter E. Brown at CPPCON'14 in his talk on modern template metaprogramming.
template <class... >
using void_t = void;
template <class T>
using has_opr_t = decltype(&T::operator());
template <class T, class = void>
struct is_callable : std::false_type { };
template <class T>
struct is_callable<T, void_t<has_opr_t<typename std::decay<T>::type>>> : std::true_type { };
Here is another implementation.
It makes use of std::is_function template for free functions.
For classes, it uses something similar to the Member Detector Idiom. If T has a call operator, callable_2 will contain more than one operator(). This will cause the first can_call function to be discarded (through SFINAE) due to ambiguity failure in decltype(&callable_2<T>::operator()) and the second can_call function will return true. If T does not have a call operator, the first can_call function will be used (due to overload resolution rules).
namespace impl
{
struct callable_1 { void operator()(); };
template<typename T> struct callable_2 : T, callable_1 { };
template<typename T>
static constexpr bool can_call(decltype(&callable_2<T>::operator())*) noexcept { return false; }
template<typename>
static constexpr bool can_call(...) noexcept { return true; }
template<bool is_class, typename T>
struct is_callable : public std::is_function<T> { };
template<typename T> struct is_callable<false, T*> : public is_callable<false, T> { };
template<typename T> struct is_callable<false, T* const> : public is_callable<false, T> { };
template<typename T> struct is_callable<false, T* volatile> : public is_callable<false, T> { };
template<typename T> struct is_callable<false, T* const volatile> : public is_callable<false, T> { };
template<typename T>
struct is_callable<true, T> : public std::integral_constant<bool, can_call<T>(0)> { };
}
template<typename T>
using is_callable = impl::is_callable<std::is_class<std::remove_reference_t<T>>::value,
std::remove_reference_t<T>>;