Currently, I have a CRTP base class which utilizes a traits class to determine the return type of it's member functions. I've been playing around with C++11 and have the following code which eliminates the need for the traits class, but requires default function template parameters. Is there some way to modify this to work in visual studio 2012 which doesn't support that feature of C++11?
#include <iostream>
using namespace std;
template<typename T, typename Ignore>
struct ignore { typedef T type; };
template<typename T>
struct A
{
template<class IgnoredParam = void>
auto foo() -> decltype(declval<typename ignore<T*, IgnoredParam>::type >()->foo_impl())
{
return static_cast<T*>(this)->foo_impl();
}
};
struct B : public A<B>
{
int foo_impl() { return 0;}
};
int main()
{
B b;
int i = b.foo();
cout << i << '\n';
}
You can simply use
decltype(declval<T>()->foo_impl())
as the deferred return type.
Related
Suppose I have a template class, which depending on a template parameter, may or may not have a member int x.
This can be realized by inheriting from a base template class, which for some specialization has a member int x.
Example code:
#include <iostream>
template <bool present>
struct base;
template <>
struct base<true> { int x; };
template <bool present>
struct base { };
template <bool activate>
struct A : public base<activate> {
void print() const;
};
template <bool activate>
void A<activate>::print() const
{
if constexpr (activate) {
std::cout << "x = " << this->x << std::endl;
} else {
std::cout << "nothing" << std::endl;
}
}
int main()
{
A<true> a;
a.print();
A<false> b;
b.print();
return 0;
}
In the code above A<true> contains a member int x, inherited from base<true>, whereas A<false> does not contain it.
Now, since x is a dependent name, in order to access it, I need to use this->x or base<true>::x. This can be somewhat burdersome to use it every time, so the common solution is to employ a using directive like
using base<true>::x;
inside the definition of A. But, of course, this makes sense only when activate=true.
Is it possible, perhaps with a macro, to add using base<true>::x in the definition of A, only when a condition (here activate=true) is satisfied?
It's a common issue to have optionally present members. If you're okay with multiple inheritance and some hacking, you can do this via a static empty variable in another base class:
struct Nothing {};
struct StaticNothing {
static Nothing x;
};
template <bool activate>
struct A : public base<activate>, StaticNothing {
using std::conditional_t<activate, base<true>, StaticNothing>::x;
void print() const;
};
Demo
Note that std::conditional_t<> decides which base x comes from. The benefit of this method is, you can always assume that there's an x member (either static or non-static), so you can take the address of it, etc.
another placeholder option is use a function, with the benefit that one can delete it to prevent unwanted access.
template <bool present>
struct base { constexpr void x()=delete; };
template <>
struct base<true> { int x = 0; };
template <bool activate>
struct A : public base<activate> {
using base<activate>::x;
void print() const{
auto&& p = x; // fail for A<false>::print
}
};
base on the comment of #Jarod42, but use anonymous class (optional) and inline variable to make sure it compiles without extra definitions. (regarding to OP's this comment)
template <bool present>
struct base { constexpr static struct{} x = {}; };
template <>
struct base<true> { int x = 0; };
template <bool activate>
struct A : public base<activate> {
using base<activate>::x;
void print() const;
};
I have a parent class and some classes derived from it. I want to 'pair' two derived classes that eac has a pointer to another one.
Code example:
template<typename DerivedClassName>
class Parent {
// some stuff
DerivedClassName* prtToPair;
};
template<typename DerivedClassName>
class DerivedA : public Parent<DerivedClassName> {
};
template<typename DerivedClassName>
class DerivedB : public Parent<DerivedClassName> {
};
// compile fails
DerivedA<DerivedB> dA;
DerivedB<DerivedA> dB;
dA.prtToPair = &dB;
dB.prtToPair = &dA;
I know I can do this with virtual function but I try to find a way to use template.
I found a solution from http://qscribble.blogspot.com/2008/06/circular-template-references-in-c.html:
#include <stdio.h>
template<class Combo> struct A
{
typedef typename Combo::b_t B;
B* b;
};
template<class Combo> struct B
{
typedef typename Combo::a_t A;
A* a;
};
struct MyCombo {
typedef A<MyCombo> a_t;
typedef B<MyCombo> b_t;
};
int main(int argc, char* argv[])
{
A<MyCombo> a;
B<MyCombo> b;
a.b = &b;
b.a = &a;
return 0;
}
but it only works for two fixed classes A and B. Consider I have many derived classes and I want to 'pair' any two of them, how can I solve this problem?
Update 1. fix a typo in first code block
Update 2. I tried following code
template<typename DerivedClassName>
class Parent {
// some stuff
public:
DerivedClassName *prtToPair;
};
template<typename DerivedClassName>
class DerivedA : public Parent<DerivedClassName> {
public:
void func() {
std::cout << "A" << std::endl;
}
};
template<typename DerivedClassName>
class DerivedB : public Parent<DerivedClassName> {
public:
void func() {
std::cout << "B" << std::endl;
}
};
int main() {
DerivedA<DerivedB<void>> A;
DerivedB<DerivedA<void>> B;
A.prtToPair = reinterpret_cast<DerivedB<void> *>(&B);
B.prtToPair = reinterpret_cast<DerivedA<void> *>(&A);
A.prtToPair->func();
B.prtToPair->func();
return 0;
}
It compiled and printed B A. But is this code correc? Does it have any side effect?
Something like the following?
#include <type_traits>
template <typename Combo>
struct Parent {
// some stuff
typename Combo::other_type* prtToPair;
};
template <typename Combo>
class DerivedA : public Parent<Combo> {};
template <typename Combo>
class DerivedB : public Parent<Combo> {};
template <template <typename...> class T, template <typename...> class U>
struct Combo {
private:
template <typename Combo, bool B>
struct impl {
using other_type =
typename std::conditional_t<B, typename Combo::type2, typename Combo::type1>;
};
public:
using type1 = T<impl<Combo, true>>;
using type2 = U<impl<Combo, false>>;
};
int main() {
using C = Combo<DerivedA, DerivedB>;
using A = typename C::type1;
using B = typename C::type2;
A dA;
B dB;
dA.prtToPair = &dB;
dB.prtToPair = &dA;
}
It makes the two types dependent on the Combo they are associated with and the choice of the correct other_type is made part of the implementation of Combo. Note that Combo<DerivedA, DerivedB> and Combo<DerivedB, DerivedA> will now lead to different types, though.
Regarding your edit:
Accessing a value through the pointer returned by reinterpret_cast to an unrelated type or calling a non-static member function using it (as you are doing) causes undefined behavior.
DerivedB isn't a class; it's a template. You can't just have a DerivedA<DerivedB>, because that doesn't make sense. What kind of DerivedB is inside DerivedA? If you think that way, you see the problem: the types of your two variables are infinite: one of them is DerivedA<DerivedB<DerivedA<DerivedB<...>>>> and the other is DerivedB<DerivedA<DerivedB<DerivedA<...>>>>. You can't have an infinite type. You must use a wrapper class somewhere to break the cycle. A generic wrapper type for this situation is
template<template<typename> typename F, template<typename> typename... Fs>
struct Fix {
F<Fix<Fs..., F>> unwrapped;
};
Fix<F1, F2, ..., Fn> represents F1<F2<...<Fn<F1<F2<...>>>>...>>. You can get your two objects as so:
Fix<DerivedA, DerivedB> dA;
Fix<DerivedB, DerivedA> dB;
dA.unwrapped.prtToPair = &dB;
dB.unwrapped.prtToPair = &dA;
Is it possible to create a class template with a member function definition only if the object created is of a specific type?
I've created a template class I will use for storing either int or doubles, but for doubles I would like to be able to set precision too (objects created with myclass < double> should have this functionality, but for myclass< int> there is no need for that to be present at all).
I know I can use a base class template, and create new classes "myInt", "myDouble" using that and implement the functionality only in the myDouble class, but I think it would be cleaner to define the functionality (both the function and a member variable) for doubles in the class template, if that's possible and preferable?
Let's add an example to show what I want to do:
#include <iostream>
#include <iomanip>
class commonBase{
public:
void setState(int state);
virtual void print() = 0;
private:
int _my_state;
};
template <typename T>
class generalObject : public commonBase {
public:
void value(T value);
void print(){ std::cout << "My value: " << _my_value << std::endl; }
private:
T _my_value;
};
template <typename T>
void generalObject<T>::value(T value){
_my_value = value;
}
// Is there any way do specialize only only whats different from the generalObject template?
// Here I thought I could specialize the case where a generalObject is created of <double>, but
// when I do, nothing is derived from generalObject (or at least not visible as far as I can tell)
template<>
class generalObject<double>{
public:
void setPrecision(int precision){ _my_precision = precision; }
// here I would like a special implementation of print(), which overrides the print() in generalObject
// and instead also prints according to the precision set when the object is of <double> type.
// Row below an example which doesn't work (compiler error, _my_value undefined)
void print(){ std::cout << "My value: " << std::setprecision(_my_precision) << _my_value << std::endl; }
private:
int _my_precision;
};
int main(int argc, char* argv[]){
generalObject<int> o1;
o1.value(1);
o1.print();
o1.setState(1); //inherited from the commonBase
generalObject<double> o2;
o2.setPrecision(2);
o2.value(2); //here value isn't available (compile error)
o2.print();
o2.setState(123); //also isn't available (compile error)
}
Sure.
template <typename T> class Poly;
void set_precision(Poly<double>* self, int a) {};
If you really want dot notation you can then add:
template <typename T> class Poly {
public: void set_precision(int a){::set_precision(this,a);}
...
However I think you should think about what you're trying to accomplish. If MyInt and MyDouble have different fields and different methods and different implementations, they should probably be different classes.
This can be solved using template specialization.
We first define a common template...
template< typename T >
struct myclass
{
// common stuff
};
... and specialize that for double:
template<>
struct myclass<double>
{
int precision = 10;
void setprecision( int p ){ precision = p; }
};
Now the setprecision() method can only be called for myclass<double>. The compiler will complain if we try to call it for anything else, like myclass<int>.
int main()
{
myclass<double> d;
d.setprecision( 42 ); // compiles
myclass<int> i;
i.setprecision( 42 ); // fails to compile, as expected
}
Demo.
The basic way to have a member function of a class template exist only for some template parameters is to create a specialization of the class template for those template parameters.
template<typename T>class X{
// general definition
};
template<>class X<double>{
// double-specific definition
};
The downside of this is that the specialization will need to duplicate anything that is common. One way to address this is to move the common things out to a base class template:
template<typename T>class Xcommon{
// common stuff
};
template<typename T>class X: public Xcommon<T>{
// general definition
};
template<>class X<double>: public Xcommon<double>{
// double-specific definition
};
Alternatively, you can do it the other way: put the common stuff in the derived class, and the extras in the base, and specialize the base:
template<typename T>class Xextras{
// empty by default
};
template<typename T>class X: public Xextras<T>{
// common definition
};
template<>class Xextras<double>{
// double-specific definition
};
Either way can work; which is better depends on the details.
Both these methods work for data members and member functions.
Alternatively, you can use enable_if to mean that member functions are not selected by overload resolution if the template parameter doesn't meet a required condition. This requires that the member function is itself a template.
template<typename T>class X{
template<typename U=T> // make it a template,
std::enable_if<std::is_same_v<U,double>> double_specific_function(){
// do stuff
}
};
I wouldn't recommend this option unless there is no other choice.
If the question is about a member function, then here is one of the ways to do it without class template specialization:
#include <iostream>
#include <type_traits>
template <typename T>
struct Type {
template <typename U = T,
typename = typename std::enable_if<std::is_same<U, double>::value>::type>
void only_for_double() {
std::cout << "a doubling" << std::endl;
}
};
int main() {
Type<int> n;
Type<double> d;
// n.only_for_double(); // does not compile.
d.only_for_double();
}
Example on ideone.com
If you require a data-member presence based on the template parameter, you will have to do some kind of specialization, in which case it is, probably, simpler to put the function into corresponding specialization.
EDIT: After OP made his question more specific
Here is one way to do it without extra class and getting rid of virtual functions. Hope it helps.
#include <iostream>
#include <iomanip>
template <typename T, typename Derived = void>
class commonBase {
public:
void setState(int state) {
_my_state = state;
}
void value(T value) {
_my_value = value;
}
template <typename U = Derived,
typename std::enable_if<std::is_same<U, void>::value,
void * >::type = nullptr>
void print() const {
std::cout << "My value: " << _my_value << std::endl;
}
template <typename U = Derived,
typename std::enable_if<!std::is_same<U, void>::value,
void * >::type = nullptr>
void print() const {
static_cast<Derived const *>(this)->_print();
}
protected:
T _my_value;
int _my_state;
};
template <typename T>
class generalObject : public commonBase<T> {
};
template<>
class generalObject<double> : public commonBase<double, generalObject<double>> {
private:
friend commonBase<double, generalObject<double>>;
void _print() const {
std::cout << "My value: " << std::setprecision(_my_precision) <<
_my_value << std::endl;
}
public:
void setPrecision(int precision){ _my_precision = precision; }
private:
int _my_precision;
};
int main(){
generalObject<int> o1;
o1.value(1);
o1.print();
o1.setState(1);
generalObject<double> o2;
o2.setPrecision(2);
o2.value(1.234);
o2.print();
o2.setState(123);
}
Same code on ideone.com
In this question I am led to a particular solution which involves partial specializations of templatized alias declarations. The generic case is described in this answer. Suppose I have a template class
template<typename T, ...>
class X {
// ....
};
Rather than leaving T free and specializing the other template parameters I am in a situation in which the other arguments depend on T, and on T alone. As a very concrete example (more manageable than the example in the other question) consider a template class
template<typename T, T absVal(T)>
class Number_impl {
private:
T _t;
public:
Number_impl(T t): _t(t) {}
T abs() const {return absVal(_t);}
};
Possible specializations are
Number_impl<int, std::abs>;
and
Number_impl<double, std::fabs>;
(I know there are overloaded abs versions, this is just for the sake of illustration. See my other example if you want).
Ideally I would like to define a template class Number depending on a single argument, the type, so that Number<int> is equal to
Number_impl<int, std::abs>;
and Number<double> is equal to
Number_impl<double, std::fabs>;
Something like the following (which doesn't work):
template<typename T>
using Number = Number_impl<T, nullptr>;
template<>
using Number<int> = Number_impl<int, std::abs>;
template<>
using Number<double> = Number_impl<double, std::fabs>;
Does anyone know if and how this can be made to work, or how the same can be achieved in a different way?
The normal way to do this kind of thing is the same way the standard library does it - with a traits class that you can specialise:
#include <iostream>
#include <cmath>
template<typename T> struct NumberTraits;
template<typename T, class Traits = NumberTraits<T>>
class Number {
private:
T _t;
public:
Number(T t): _t(t) {}
T abs() const {
return Traits::abs(_t);
}
};
template<> struct NumberTraits<int>
{
static int abs(int i) {
return std::abs(i);
}
};
template<> struct NumberTraits<double>
{
static double abs(double i) {
return std::fabs(i);
}
};
using namespace std;
auto main() -> int
{
Number<int> a(-6);
Number<double> b(-8.4);
cout << a.abs() << ", " << b.abs() << endl;
return 0;
}
expected output:
6, 8.4
You may add a layer:
template<typename T, T absVal(T)>
class Number_impl {
private:
T _t;
public:
Number_impl(T t): _t(t) {}
T abs() const {return absVal(_t);}
};
template<typename T> struct Number_helper;
template<> struct Number_helper<int> { using type = Number_impl<int, std::abs>; };
template<> struct Number_helper<double> { using type = Number_impl<double, std::fabs>; };
template<typename T>
using Number = typename Number_helper<T>::type;
How can someone make this code compile:
#include <iostream>
using namespace std;
enum E { A, B};
template< E x>
class C {
public:
#if( x == A)
static void foo() {
cout << "A";
}
#elif( x == B)
static void goo() {
cout << "B";
}
#endif
};
int main() {
C< A>::foo();
C< B>::goo();
return 0;
}
error: ‘goo’ is not a member of ‘C<(E)1u>’
I have two big classes which differs only a few lines, so I wanted to make enum template. The problem is that this lines have using keyword in them, so I don't know what to put there.
Is there some correct way to do it?
PS> I'm have to use C++03.
EDIT: A little clarification. I know about template<> construction, but I don't wanted to use it because this way I got a lot of code duplication. Maybe I can somehow make partial "template instanciation" (if this is correct term for template<>)?
Suppose I have two classes (and I will not have more):
class A {
public:
//…a lot of code…
//few lines that differs in A and B
}
class B {
//…the same mass of code…
//few lines that differs in A and B
}
So I decided to make template on enum:
enum E { A, B}
template< E>
class C{
//…common code…
}
Now I don't know what to do with this few lines that differs in A and B. I know that common way is to make template instanciation, but then I'll get exactly what I had with classes A and B.
From the OOP point I should use common Base for A and B. But the problem is that A and B is already the same. They differs only with line:
using CanStoreKeyValue< QString, Request>::set;
using CanStoreKeyValue< QString, Response>::set;
where Response and Request are typedefs. Moreover, in my code A and B are childs of the same templated abstract class. And of course they inherit it with different template param. This somehow brokes using of template enum — compiler just can't see that some virtual methods a no longer pure. So… that's why I'm asking what I'm asking. I thought that preprocessor could interact with template engine with #if-directives (on the end, they both are compile time processes).
You cannot use preprocessor to achieve what you are trying to do. What you need is a template specialization:
enum E { A, B};
template< E x>
class C;
template <>
class C<A> {
public:
static void foo() {
cout << "A";
}
};
template <>
class C<B> {
public:
static void goo() {
cout << "B";
}
};
Your updated problem still can be resolved by template specialization:
enum E { A, B };
template< E x >
struct CanStoreKeyValueHelper;
template<>
struct CanStoreKeyValueHelper<A> {
typedef CanStoreKeyValue< QString, Request>::set type;
};
template<>
struct CanStoreKeyValueHelper<B> {
typedef CanStoreKeyValue< QString, Response>::set type;
};
template< E x>
class SuperPuperBigClass {
public:
typedef typename CanStoreKeyValueHelper<x>::type set;
...
};
But it is not clear why you do not make it as simple as:
template<class T>
class SuperPuperBigClass {
public:
typedef typename CanStoreKeyValue<QString, T>::set set;
};
and instantiate it with Request and Response type
If you don't want specialization, I suppose constraining the functions with SFINAE is an option (Live at coliru):
template <E x>
class C {
public:
template <E y = x>
static typename std::enable_if<y == A>::type foo() {
cout << "A";
}
template <E y = x>
static typename std::enable_if<y == B>::type goo() {
cout << "B";
}
};
But if code duplication is your only issue, use specialization and put the common code in a base class (Live at Coliru), it's a bit cleaner:
class C_base {};
template <E x>
class C : public C_base {};
template <>
class C<A> : public C_base {
public:
static void foo() {
cout << "A";
}
};
template <>
class C<B> : public C_base {
public:
static void goo() {
cout << "B";
}
};