Multiple inheritance with templated template - c++

I want to do multiple inheritance via template arguments and pass reference to this in each base class, so I can call top level object's method from each base class's method. I can do it with manual inheritance, but I want to be able to do this via templates arguments.
Godbolt link
Godbolt link with manual inheritance
#include <cstdio>
template <typename T>
struct Foo {
Foo(T &t)
: t_(t) {
}
void foo() {
t_.call("foo");
}
T &t_;
};
template <typename T>
struct Bar {
Bar(T &t)
: t_(t) {
}
void bar() {
t_.call("bar");
}
T &t_;
};
template <template<typename> typename... Methods>
struct Impl : public Methods<Impl>... {
Impl()
: Methods<Impl>(*this)... {
}
void call(const char *m) {
printf(m);
}
};
int main() {
auto t = Impl<Foo, Bar>();
t.foo();
t.bar();
}
I tried this approach, but it gives
type/value mismatch at argument 1 in template parameter list for 'template<class> class ... Methods'

Thanks to #Nicol Bolas, he advised to use static_cast and CRTP for this
#include <cstdio>
template <typename T>
struct Foo {
void foo() {
static_cast<T*>(this)->call("foo");
}
};
template <typename T>
struct Bar {
void bar() {
static_cast<T*>(this)->call("bar");
}
};
template <template<typename> typename... Methods>
struct Impl : public Methods<Impl<Methods...>>... {
Impl() {
}
void call(const char *m) {
printf(m);
}
};
int main() {
auto t = Impl<Foo, Bar>();
t.foo();
t.bar();
}

Related

derived class as a parameter of templated function which is specialized for its base class

class Base {};
class Derived : public Base {};
class SomeClass
{
template<typename T>
static void SetContent(T* pChild, OVariant content)
{
LOG_ASSERT(0, "All classes must be specialized!. Please provide implementation for this class.");
}
};
template <>
void SomeClass::SetContent(Base* value)
{
LOG_TRACE("Yay!");
}
int main() {
SomeClass foo;
Derived derived;
foo.SetContent(&derived);//want it to call SomeClass::SetContent(Base* value)
return 0;
}
When I call foo.SetContent(derived), I get the Assert. Is it not possible for the derived class to use the specialization for it's base class?
You can convert a Derived* to a Base*, but I think you rather want to specialize for all T that have Base as base
#include <type_traits>
#include <iostream>
class Base {};
class Derived : public Base {};
template <typename T,typename = void>
struct impl {
void operator()(T*) {
std::cout <<"All classes must be specialized!. Please provide implementation for this class.\n";
}
};
template <typename T>
struct impl<T,std::enable_if_t<std::is_base_of_v<Base,T>>> {
void operator()(T*) {
std::cout << "Yay\n";
}
};
class SomeClass
{
public:
template<typename T>
static void SetContent(T* pChild)
{
impl<T>{}(pChild);
}
};
struct bar{};
int main() {
SomeClass foo;
Derived derived;
foo.SetContent(&derived);
bar b;
foo.SetContent(&b);
}
Output:
Yay
All classes must be specialized!. Please provide implementation for this class.
//want it to call SomeClass::SetContent(Base* value)
Note that if the template argument is deduced, it will be deduced as Derived not as Base and the argument is Derived*. SomeClass::SetContent<Base>(&derived); would already work as expected with your code (because Derived* can be converted to Base*).
A workaround would be to have all SetContent's explicit specializations to form an overload set. You will have to do it yourself:
#include <iostream>
#include <utility>
#include <functional>
class Base {};
class Derived : public Base {};
template <class... T>
struct Overloads : T... {
Overloads(const T &... t) : T(t)... {}
using T::operator()...;
};
template <class R, class... Args>
struct FunctionP {
using F = R(Args...);
FunctionP(F *t) : t_(t) {}
R operator()(Args... args) const {
return std::invoke(t_, std::forward<Args>(args)...);
}
F *t_;
};
struct SomeClass {
template<typename T>
static void SetContent(T *x) {
Overloads o(FunctionP(&SetContentImpl<Base>)); // enumerates all the specializations here
if constexpr (std::is_invocable_v<decltype(o), T *>) {
o(x);
} else {
SetContentImpl(x);
}
}
template<typename T>
static void SetContentImpl(T *) {
std::cout << "1";
}
};
template <>
void SomeClass::SetContentImpl(Base *) {
std::cout << "2";
}
int main() {
SomeClass foo;
Derived derived;
foo.SetContent(&derived);//want it to call SomeClass::SetContent(Base* value)
return 0;
}
godbolt

Template member function specialization of a templated class without specifying the class template parameter

What is the correct syntax to specialize a templated member function of a templated class without specifying the class template parameter?
Here is what I mean:
Example #1 (works):
#include <iostream>
struct C1
{
template <class B>
void f(void) const;
};
template <>
void C1::f<int>(void) const { std::cout<<777<<std::endl; }
int main(void)
{
C1 c1; c1.f<int>();
}
Example #2 (works):
#include <iostream>
template <class A>
struct C2
{
template <class B>
void f(void) const;
};
template <>
template <>
void C2<int>::f<int>(void) const { std::cout<<888<<std::endl; }
int main(void)
{
C2<int> c2; c2.f<int>();
return 0;
}
Example #3 (does not compile: "enclosing class templates are not explicitly specialized"):
#include <iostream>
template <class A>
struct C3
{
template <class B>
void f(void) const;
};
struct D { static int g(void){ return 999; } };
template <class A>
template <>
void C3<A>::f<int>(void) const { std::cout<<A::g()+1<<std::endl; }
template <class A>
template <>
void C3<A>::f<char>(void) const { std::cout<<A::g()+2<<std::endl; }
int main(void)
{
C3<D> c3a; c3a.f<int >(); // expect to see 1000
C3<D> c3b; c3b.f<char>(); // expect to see 1001
return 0;
}
How can I make example #3 work?
You can use a technique called tag dispatch and replace the template specialisations by function overloads.
template<typename>
struct Tag {};
template <class A>
struct C3
{
void f_impl(Tag<int>) const;
void f_impl(Tag<char>) const;
template<class B>
void f() const {
f_impl(Tag<B>{});
}
};
struct D { static int g(void){ return 999; } };
template <class A>
void C3<A>::f_impl(Tag<int>) const { std::cout<<A::g()+1<<std::endl; }
template <class A>
void C3<A>::f_impl(Tag<char>) const { std::cout<<A::g()+2<<std::endl; }
Then your call site looks exactly as you want:
C3<D> c3; c3.f<int>(); // expect to see 1000
C3<D> c4; c4.f<char>(); // expect to see 1001
Full example here.

In a template, if a dependent name is a function, call it

In my TClass<T>::foo() function, I'd like to invoke a T instance if and only if T is a function type.
#include <iostream>
#include <functional>
template<class T>
struct TClass
{
TClass(T value) : value(value) {}
T value;
void foo()
{
// if(value is std::function)
// call function;
}
};
int main()
{
TClass<int> t1{0};
t1.foo();
TClass<std::function<void()>> t2{[](){ std::cout << "Hello, World!\n"; }};
t2.foo();
}
How can I do that?
In C++11, the easiest way to do this is to re-deduce the value through a helper function:
template <typename U>
auto foo_helper(U const& f, int) -> decltype(f()) {
return f();
}
template <typename U>
void foo_helper(U const&, long) {}
void foo() {
foo_helper(value, 0);
}
The conversion from 0 to int is better than its conversion to long, so if the first overload is viable - it will be preferred. If the first overload isn't viable, then we call the second one.
If you really care only about std::function, then we can just have simpler overloads:
void foo_helper(std::function<void()> const& f) {
f();
}
template <typename T>
void foo_helper(T const&) { }
void foo() {
foo_helper(value);
}
In C++17 you can do:
void foo() {
if constexpr (std::is_invocable_v<T>) {
value();
}
}
If you only wants to allow std::function, you'll need your own trait, e.g.:
template <class T>
struct is_stdfunction: std::false_type {};
template <class T>
struct is_stdfunction<std::function<T>: std::true_type {};
template <class T>
constexpr bool is_stdfunction_v = is_stdfunction<T>::value;
// Then in foo():
void foo() {
if constexpr (is_stdfunction_v<std::decay_t<T>>) {
value();
}
}
Why not partial specialization ?
Consider:
#include <iostream>
#include <functional>
template<class T>
struct TClass {
TClass(T value) : value(value) {}
T value;
void foo() {
std::cout << "T - other" << std::endl;
}
};
template<class T>
struct TClass<std::function<T>> {
TClass(std::function<T> value) : value(value) {}
std::function<T> value;
void foo() {
std::cout << "std::function" << std::endl;
}
};

C++ template specialization for interface

Why won't the compiler select the Interface template when running the following code? Are additional declarations / hints needed or won't this work in general?
I'm just curious if this is actually possible.
class Interface {
public :
virtual void Method() = 0;
virtual ~Interface() { }
};
class Derived : Interface {
public :
void Method() {
cout<<"Interface method"<<endl;
}
};
template<typename T>
struct Selector {
static void Select(T& o) {
cout<<"Generic method"<<endl;
}
};
template<>
struct Selector<Interface> {
static void Select(Interface& o) {
o.Method();
}
};
int i;
Selector<int>::Select(i) // prints out "Generic method" -> ok
Derived d;
Selector<Derived>::Select(d); // prints out "Generic method" -> wrong
// should be "Interface method"
Try this (and #include <type_traits>):
template <typename T, typename = void>
struct Selector
{
static void Select(T & o)
{
std::cout << "Generic method" << std::endl;
}
};
template <typename T>
struct Selector<T,
typename std::enable_if<std::is_base_of<Interface, T>::value>::type>
{
static void Select(Interface & o)
{
o.Method();
}
};
It turns out that enable_if combined with defaulted template arguments can be used to guide partial specialisations.
The compiler will select the version of a function that is the closest match. A function that takes the exact type for a parameter always wins over one that requires a conversion. In this case the template function is an exact match, since it matches anything; the Interface specialization would require the conversion of the parameter from a Derived to an Interface.
This will allow you to achieve the desired result:
#include <iostream>
#include <type_traits>
using namespace std;
class Interface {
public :
virtual void Method() = 0;
virtual ~Interface() { }
};
class Derived : public Interface {
public :
void Method() {
cout<<"Interface method"<<endl;
}
};
template<typename T, typename S = void>
struct Selector {
static void Select(T& o) {
cout<<"Generic method"<<endl;
}
};
template<typename T>
struct Selector<T, typename enable_if< is_base_of<Interface, T>::value >::type> {
static void Select(Interface& o) {
o.Method();
}
};
int main()
{
int i;
Selector<int>::Select(i); // prints out "Generic method" -> ok
Derived d;
Selector<Derived>::Select(d); // prints out "Generic method" -> wrong
// should be "Interface method"
}

boost concept check operator() overload

template <typename T, typename C>
class CSVWriter{
template <typename PrinterT>
void write(std::ostream& stream, const PrinterT& printer){
}
};
I want to check whether there exists at least two overloads PrinterT::operator()(T*) and PrinterT::operator()(C*)
PrinterT may or may not inherit from std::unary_function
What concept Checking Classes I need to use here ?
(I am not using C++11)
You can use something like that
#include <iostream>
#include <boost/concept/requires.hpp>
#include <boost/concept/usage.hpp>
template <class Type, class Param>
class has_operator_round_brackets_with_parameter
{
public:
BOOST_CONCEPT_USAGE(has_operator_round_brackets_with_parameter)
{
_t(_p);
}
private:
Type _t;
Param _p;
};
struct X {};
struct Y {};
struct Test1
{
void operator() (X*) const { }
};
struct Test2: public Test1
{
void operator() (X*) const { }
void operator() (Y*) const { }
};
template <class T, class C>
struct CSVWriter
{
template <class PrinterT>
BOOST_CONCEPT_REQUIRES(
((has_operator_round_brackets_with_parameter<PrinterT, T*>))
((has_operator_round_brackets_with_parameter<PrinterT, C*>)),
(void)) write(std::ostream& stream, const PrinterT& printer)
{
}
};
int main()
{
CSVWriter<X, Y> w;
// w.write<Test1>(std::cout, Test1()); // FAIL
w.write<Test2>(std::cout, Test2()); // OK
return 0;
}