c++, using enable_if along with existing template class? - c++

I have existing template class A,B that cannot be changed.
template<class T>
struct A{static void F(){}};
template<int I>
struct B{};
I want to specialize A only when T is B<I> and 1<=I<=5.
If A can be changed, it would be like the following :
template<class T,class = void>//added second param
struct A{static void F(){}};
template<int I>
struct B{};
template<int I>
struct A< B<I>, std::enable_if_t<(1<=I&&I<=5)> >{static void F(){}};
int main(){
A<B<0>>::F();//call origin ver
A<B<1>>::F();//call specialized ver
A<B<10>>::F();//call origin ver
}
Is it possible?

You could redirect the specialization into inheriting from a conditional implementation
template<class T>
struct A{
static void F() { std::cout << "default\n"; }
};
template<int I>
struct B{};
struct tag{};
template<int I>
struct ABImpl {
static void F() { std::cout << "specialized for " << I << '\n'; }
};
template<int I>
struct A<B<I>> : std::conditional_t<1 <= I && I <= 5, ABImpl<I>, A<tag>> {};
The tag is a dummy that' simply used for grabbing a default implementation without risk of conflict.
Live Example

Add one layer of indirection.
template <class T>
struct SpecializedA {
//... specialized implementation
};
template<class T,class = void>//added second param
struct MyA_impl{
using type = A<T>;
};
template<int I>
struct MyA_impl< B<I>, std::enable_if_t<(1<=I&&I<=5)> >{
using type = SpecializedA<B<I>>;
};
template <typename T>
using MyA = typename MyA_impl<T>::type;
With that we get
MyA<B<0>> == A<B<0>>
MyA<B<1>> == SpecializedA<B<1>>
MyA<int> == A<int>

Related

Check if a type is the same as a templated type

I have a user defined class
template<typename T, int N>
class MyClass
{
// Implementation
};
and I want to check on the instantiation of another class if its template parameter is an instance of MyClass
template<typename T, std::enable_if_t<!is_MyClass<T>, bool> = true>
class MapClass
{
// custom stuff here
};
template<typename T, std::enable_if_t<is_MyClass<T>, bool> = true>
class MapClass
{
// Some more stuff here
};
I tried to implement it like this but my instantiation fails because it requires two parameters. How do I make automatically extract both parameters
template <typename T> struct is_MyClass : std::false_type {};
template <typename T, int N> struct is_MyClass<MyClass<T, N>> : std::true_type {};
Thanks
I suggest to write a trait is_instantiation_of_myClass that uses partial specialization:
template<typename T, int N>
class MyClass {};
template <typename C>
struct is_instantiation_of_myClass : std::false_type {};
template <typename T,int N>
struct is_instantiation_of_myClass<MyClass<T,N>> : std::true_type {};
template <typename C>
constexpr bool is_instantiation_of_myClass_v = is_instantiation_of_myClass<C>::value;
Now you can do SFINAE based on is_instantiation_of_myClass<T> or just plain specialization:
template <typename T,bool = is_instantiation_of_myClass_v<T>>
struct Foo;
template <typename T>
struct Foo<T,true> {
static constexpr bool value = true;
};
template <typename T>
struct Foo<T,false> {
static constexpr bool value = false;
};
int main() {
std::cout << Foo< int >::value << "\n";
std::cout << Foo< MyClass<int,42>>::value << "\n";
}
Live Demo

How to tell if template type is an instance of a non-variadic template class?

This question is awful similar to How to tell if template type is an instance of a template class?
I would like to detect if a template parameter is from one particular template class that has no variadic template arguments.
template<class U, class S>
struct A{};
template<class T>
struct B {
B() {
if constexpr (T == A) {
// T is a template instantiation of `A`.
} else {
}
}
};
I can't change A's definition. I can change B's definition to have additional template parameters.
How do I implement (T == A) given the restriction of not knowing A's U and S?
I would go for a partial specialization here.
#include <iostream>
template<class U, class S>
struct A{};
template<class T>
struct B {
B() {
std::cout << "None-A implementation\n";
}
};
template<class U, class S>
struct B<A<U, S>> {
B() {
std::cout << "A implementation\n";
}
};
int main() {
B<int> b1;
B<A<int, int>> b2;
}
You have the option of leaving the default-case without an implementation.
Or you can have a fallback implementation for any none-A classes like here.
If the partial specialization forces too much code duplication you can also extract the detection part to it's own template variable like this.
#include <iostream>
template<class U, class S>
struct A{};
template <class T>
constexpr bool is_A_instatiation = false;
template <class U, class S>
constexpr bool is_A_instatiation<A<U, S>> = true;
template<class T>
struct B {
B() {
if constexpr (is_A_instatiation<T>) {
std::cout << "A instatiation!\n";
} else {
std::cout << "none-A instatiation!\n";
}
}
};
int main() {
B<int> b1;
B<A<int, int>> b2;
}
The easiest way is:
template<class T>
struct B{/*default implementation*/};
template<class U,class S>
struct B<A<U,S>>{/*Specified implementation*/};
A<T,U>: you already know it and search key
B<...>: variadic types which may include A<T,U> - known type
And you want to search A<T,U> in B<...>
template <typename T, typename U>
struct A {};
template <typename T, typename U, typename ...Ts>
struct B {
static constexpr bool value = ((std::is_same_v< A<T, U>, Ts> || ... ));
};
int main() {
std::cout << std::boolalpha <<
B<int,float, int, int, float, A<int,float>>::value << '\n'<<
B<int,float, int, int, float>::value <<std::endl;
}

Better pattern for partial specialization disambiguation precedence chain?

Consider the following series of partial specializations:
template <typename T, typename Enable=void>
struct foo {
void operator()() const { cout << "unspecialized" << endl; }
};
template <typename T>
struct foo<T, enable_if_t<
is_integral<T>::value
>>{
void operator()() const { cout << "is_integral" << endl; }
};
template <typename T>
struct foo<T, enable_if_t<
sizeof(T) == 4
and not is_integral<T>::value
>>{
void operator()() const { cout << "size 4" << endl; }
};
template <typename T>
struct foo<T, enable_if_t<
is_fundamental<T>::value
and not (sizeof(T) == 4)
and not is_integral<T>::value
>>{
void operator()() const { cout << "fundamental" << endl; }
};
// etc...
Live Demo
I see this kind of thing all of the time (indeed, another StackOverflow answer elsewhere gives the same pattern for a similar problem). While this works, this code has some serious maintainability issues, and also precludes, e.g., user-level partial specializations at higher priority if the above code is in a library. What's a better pattern for expressing this idea? I feel like there has to be something (maybe involving inheritance and variadic template parameters?) that can express this idea more cleanly and maintainably. (Suppose also that each of the specializations is a full-on class rather than a simple functor, so overloaded functions don't work in a simplistic way).
The overgrowth of condition count can be solved by helper structs:
#include <iostream>
#include <type_traits>
using namespace std;
template <bool ThisCondition, class ParentCondition = void, class = void>
struct condition_resolver {
static constexpr bool is_condition_resolver = true;
static constexpr bool parent_condition_v = !ThisCondition;
static constexpr bool value = ThisCondition;
};
template <bool ThisCondition, class ParentCondition>
struct condition_resolver<ThisCondition, ParentCondition, enable_if_t<ParentCondition::is_condition_resolver> > {
static constexpr bool is_condition_resolver = true;
static constexpr bool parent_condition_v = !ThisCondition && ParentCondition::parent_condition_v;
static constexpr bool value = ThisCondition && ParentCondition::parent_condition_v;
};
template <typename T, typename Enable=void>
struct foo {
void operator()() const { cout << "unspecialized" << endl; }
};
template <typename T>
struct is_integral_foo: condition_resolver<is_integral<T>::value> { };
template <typename T>
struct foo<T, enable_if_t<is_integral_foo<T>::value>>{
void operator()() const { cout << "is_integral" << endl; }
};
template <typename T>
struct has_size_four_foo: condition_resolver<sizeof(T) == 4, is_integral_foo<T>> { };
template <typename T>
struct foo<T, enable_if_t< has_size_four_foo<T>::value>>{
void operator()() const { cout << "size 4" << endl; }
};
template <typename T>
struct is_fundamental_foo: condition_resolver<is_fundamental<T>::value, has_size_four_foo<T>> { };
template <typename T>
struct foo<T, enable_if_t<is_fundamental_foo<T>::value>>{
void operator()() const { cout << "fundamental" << endl; }
};
typedef char four_sized[4];
int main() {
foo<int>()();
foo<four_sized>()();
foo<nullptr_t>()();
}
Output:
is_integral
size 4
fundamental
PS.
Have in mind that void which is also fundamental will cause compiler to produce a warning that sizeof(void) is considered...
Edit:
If you really need to use specialization for solving the overgrowth of condition problem this might interest you:
#include <iostream>
#include <type_traits>
using namespace std;
template <class Tag, int Level, class... Args>
struct concrete_condition_resolver;
template <class Tag, int Level, class... Args>
struct condition_resolver;
template <class ConditionResolver>
struct condition_resolver_parent {
template<class CR = ConditionResolver>
constexpr enable_if_t<CR::level != 0, bool> operator()(bool parent) {
return (!parent && static_cast<const ConditionResolver*>(this)->condition && typename ConditionResolver::LevelUp()(true)) ||
(parent && !static_cast<const ConditionResolver*>(this)->condition && typename ConditionResolver::LevelUp()(true));
}
template<class CR = ConditionResolver>
constexpr enable_if_t<CR::level == 0, bool> operator()(bool parent) {
return (!parent && static_cast<const ConditionResolver*>(this)->condition) ||
(parent && !static_cast<const ConditionResolver*>(this)->condition);
}
};
template <class Tag, int Level, class... Args>
struct condition_resolver: concrete_condition_resolver<Tag, Level, Args...>, condition_resolver_parent<condition_resolver<Tag, Level, Args...>> {
using LevelUp = condition_resolver<Tag, Level - 1, Args...>;
using tag = Tag;
static constexpr int level = Level;
constexpr condition_resolver() {}
};
struct foo_tag { };
template <class First, class... Args>
struct concrete_condition_resolver<foo_tag, 0, First, Args...> {
static constexpr bool condition = is_integral<First>::value;
};
template <class First, class... Args>
struct concrete_condition_resolver<foo_tag, 1, First, Args...> {
static constexpr bool condition = sizeof(First) == 4;
};
template <class First, class... Args>
struct concrete_condition_resolver<foo_tag, 2, First, Args...> {
static constexpr bool condition = is_fundamental<First>::value;
};
template <typename T, typename = void>
struct foo;
template <typename T>
struct foo<T, enable_if_t<condition_resolver<foo_tag, 0, T>()(false)>>{
void operator()() const { cout << "is_integral" << endl; }
};
template <typename T>
struct foo<T, enable_if_t<condition_resolver<foo_tag, 1, T>()(false)>>{
void operator()() const { cout << "size 4" << endl; }
};
template <typename T>
struct foo<T, enable_if_t<condition_resolver<foo_tag, 2, T>()(false)>>{
void operator()() const { cout << "is_fundamental" << endl; }
};
typedef char four_sized[4];
int main() {
foo<int>()();
foo<four_sized>()();
foo<nullptr_t>()();
}
This approach is applicable even for overload functions using enable_if, while partial specialization deals only with structs...
Why am I answering my own question
So I've been bugged by this ever since asking this question, and I was never completely satisfied with the original answer. After much fiddling and trial/error, I've come up with a pattern I'm much happier with that uses tag dispatch. Whether or not it's actually better, more readable, and more maintainable than the previous answer is for you to judge, but I like it better. Feel free to pick it apart, criticize it, and break it. :-)
The Basic Version
Without further ado, here's the code that solve the simplest version of the problem
template <typename> struct always_true : true_type { };
template <typename> struct always_false : false_type { };
template <typename T, template <class...> class condition=always_false,
typename flag=integral_constant<bool, condition<T>::value>
>
struct foo;
////////////////////////////////////////
// "unspecialized" version
// put always_true and false_type together here so that no one gets here accidentally
template <typename T, typename true_or_false_type>
struct foo<T, always_true, true_or_false_type> {
void operator()() const { cout << "unspecialized" << endl; }
};
////////////////////////////////////////
// is_fundamental
template <typename T>
struct foo<T, is_fundamental, true_type> {
void operator()() const { cout << "is_fundamental" << endl; }
};
template <typename T> struct foo<T, is_fundamental, false_type> : foo<T, always_true> { };
////////////////////////////////////////
// is_integral
template <typename T>
struct foo<T, is_integral, true_type> {
void operator()() const { cout << "is_integral" << endl; }
};
template <typename T>
struct foo<T, is_integral, false_type> : foo<T, is_fundamental> { };
////////////////////////////////////////
// sizeof(T) == 4
template <typename T>
using size_is_4 = integral_constant<bool, sizeof(T) == 4>;
template <typename T>
struct foo<T, size_is_4, true_type> {
void operator()() const { cout << "size_is_4" << endl; }
};
template <typename T>
struct foo<T, size_is_4, false_type> : foo<T, is_integral> { };
////////////////////////////////////////
// Now put the most specialized condition in the base of this template
template <typename T, typename true_or_false_type>
struct foo<T, always_false, true_or_false_type> : foo<T, size_is_4> { };
The chain of precedence, held in a helper struct in the previous answer, is encoded in inheritance.
More bells and whistles
Adding the ability to enable user partial specializations with higher precedence than the library ones takes a little more doing, but the principle is the same. The full version in this demo.

Template method specialization for multiple types

I have a class “A” which exposes the template method foo.
Foo has a standard implementation which works fine with B,C. It also has a special implementation for D.
class A
{
template<typename T>
void foo()
{
//standard implementation
}
template<>
void foo<D>
{
//special implementation
}
}
class B{};
class C{};
class D{};
int main()
{
A<B> a1;
A<C> a2;
A<D> a3;
}
Now, I need to add the class E, which requires for "foo" the same special implementation as D.
Is there a way to say something like: For all the types use the standard foo. For D,E (and so on) the special implementation.
class A
{
template<typename T>
void foo()
{
//standard implementation
}
template<>
void foo<D && E> <-- PseudoCode - It doesn't work
{
//special implementation
}
}
class B{};
class C{};
class D{};
class E{};
int main()
{
A<B> a1;
A<C> a2;
A<D> a3;
A<E> a4;
}
I was thinking to use the trait classes. But I was hoping there is something simpler to achieve this.
Thanks
Using Walter Brown's (C++1z) void_t.
#include <iostream>
#include <type_traits>
template <typename...>
using void_t = void;
template <typename T, typename = void>
struct has_bar
: std::false_type { };
template <typename T>
struct has_bar<T, void_t<decltype( std::declval<T&>().bar() ) > >
: std::true_type { };
class A {
public:
void foo() { };
};
class B {
public:
void bar() { };
};
class C {
public:
void bar() { };
};
template <typename T>
typename std::enable_if<!has_bar<T>::value, void>::type
fun(T t) {
std::cout << "fun" << std::endl;
}
template <typename T>
typename std::enable_if<has_bar<T>::value, void>::type
fun(T t) {
std::cout << "special fun" << std::endl;
}
The code...
int main(const int argc, const char* argv[argc]) {
A a;
B b;
C c;
fun(a);
fun(b);
fun(c);
return 0;
}
prints out
fun
special fun
special fun
Note, that does not check any type semantics, so it may be better declaring bar() as an interface and using std::is_base_of.
You should take a look on SFINAE to enable and disable function at compile time
If D and E are special, they have let's say the member void bar() and not the others, you can actually implement your own type trait:
template<typename T>
struct has_bar {
private:
template<typename C> static std::true_type test(decltype(&C::bar)*);
template<typename C> static std::false_type test(...);
public:
constexpr static bool value = decltype(test<T>(nullptr))::value;
};
/* false */ /* true */
cout << boolalpha << has_bar<A> << " " << has_bar<E> << endl;
Now with this type trait you can use std::enable_if as a compile time switch:
/* standard if no bar */
template<typename T, typename = enable_if_t< !has_bar<T> >>
void foo()
{
//standard implementation
}
/* special if bar */
template<<typename T, typename = enable_if_t< has_bar<T> >>
void foo()
{
//special implementation
}
AFAIK there's no way you can do this without defining some SFINAE machinery. Now the minimum I can think of without including type_traits header would be the following:
Define "home made "enable_if and is_same type traits as follows.
namespace mine {
template<bool, typename T = void> struct enable_if {};
template<typename T> struct enable_if<true, T> { typedef T type; };
template<typename T, typename U> struct is_same { static bool const value = false; };
template<typename T> struct is_same<T, T> { static bool const value = true; };
};
Apply SFINAE in member function foo() of class A as follows:
class A {
template<typename T>
struct pred {
static bool const value = mine::is_same<T, B>::value ||
mine::is_same<T, C>::value || mine::is_same<T, D>::value || mine::is_same<T, E>::value;
};
public:
template<typename T>
typename mine::enable_if< pred<T>::value, void>::type
foo() { std::cout << "special implementation" << std::endl; }
template<typename T>
typename mine::enable_if<!pred<T>::value, void>::type
foo() {std::cout << "standard implementation" << std::endl; }
};
LIVE DEMO
P.S the bonus is that the above solution works also for pre C++11 compilers.

How to find, from which template-layers is object composed of?

How can I use templates, to find out, from which types is type composed of when using template layers?
Let's have
template <typename Super>
class A : public Super {};
template <typename Super>
class B : public Super {};
template <typename Super>
class C : public Super {};
class Blank{};
template <typename CombinedType>
void printTypeComponents(const CombinedType & t) { ... }
int main()
{
typedef A<B<C<Blank>>> ComposedType;
ComposedType ct;
printTypeComponents(ct);
typedef A<C<Blank>> ComposedType2;
ComposedType2 ct2;
printTypeComponents(ct2);
}
I am attaching my try, wrong of course (works only if object is composed from all tested types, since tested types actually exists), but you can easily see from it, what my aim is
#include <boost/type_traits/is_base_of.hpp>
#include <iostream>
template <typename Super>
class A : public Super
{
public:
typedef A<Super> AComponent;
};
template <typename Super>
class B : public Super
{
public:
typedef B<Super> BComponent;
};
template <typename Super>
class C : public Super
{
public:
typedef C<Super> CComponent;
};
class Blank{};
template <typename CombinedType>
void printTypeComponents(const CombinedType & t)
{
if(boost::is_base_of<Blank, CombinedType::AComponent>::value)
std::cout << "composed of A \n";
if(boost::is_base_of<Blank, CombinedType::BComponent>::value)
std::cout << "composed of B \n";
if(boost::is_base_of<Blank, CombinedType::CComponent>::value)
std::cout << "composed of C \n";
}
int main()
{
typedef A<B<C<Blank>>> ComposedType;
ComposedType ct;
printTypeComponents(ct);
//typedef A<C<Blank>> ComposedType2;
//ComposedType2 ct2;
//printTypeComponents(ct2);
}
I am using MSVC2010
Thank you!
EDIT:
I am not actually interested in names of types... I want to use it like:
if(composedOfA)
doSomeCharacteristicStuffFromA(); //member function of A
if(composedOfB)
doSomeCharacteristicStuffFromB(); //member function of B
My attempt (without using C++0x feature(s))
//----------------------------------------
struct null{};
template<typename>
struct split
{
typedef null Ct;
typedef null At;
};
template<template<typename> class C, typename T>
struct split<C<T> >
{
typedef C<null> Ct; //class template
typedef T At; //argument type
};
template<template<typename> class C>
struct split<C<Blank> >
{
typedef C<null> Ct; //class template
typedef Blank At; //argument type
};
template<typename T, typename U>
struct is_same
{
static const bool value = false;
};
template<typename T>
struct is_same<T,T>
{
static const bool value = true;
};
typedef A<null> anull;
typedef B<null> bnull;
typedef C<null> cnull;
//----------------------------------------
template <typename CombinedType>
void printTypeComponents(const CombinedType & t)
{
typedef typename split<CombinedType>::Ct Ct;
typedef typename split<CombinedType>::At At;
if ( is_same<Ct,anull>::value )
cout << "A" << endl;
else if ( is_same<Ct,bnull>::value )
cout << "B" << endl;
else if ( is_same<Ct,cnull>::value )
cout << "C" << endl;
if ( !is_same<At,Blank>::value )
printTypeComponents(At());
else
cout << "Blank" << endl;
}
Test code:
int main()
{
typedef A<B<C<Blank> > > ComposedType;
ComposedType ct;
printTypeComponents(ct);
cout<<"-------"<<endl;
typedef A<C<Blank> > ComposedType2;
ComposedType2 ct2;
printTypeComponents(ct2);
}
Output:
A
B
C
Blank
-------
A
C
Blank
Online Demo : http://ideone.com/T5nD4
Exploiting your structure, what about:
template <template <typename> class X, typename T>
void print_type(const X<T>& x, char (*)[std::is_base_of<T, X<T>>::value] = 0)
{
std::cout << "Base: " << typeid(T).name() << "\n";
print_type<T>(x);
}
template <typename T>
void print_type(const T&) {}
Here is a template unraveller that uses variadic typenames. You can probably make it work in VS2010 with the usual macro tricks (e.g. like in the pretty-printer.)
template <typename T> class A : public T {};
template <typename T> class B : public T {};
template <typename T> class C : public T {};
struct NullType {};
#include <tuple>
#include <iostream>
template <typename ...Args> struct Concat;
template <typename T, typename ...Args>
struct Concat<T, std::tuple<Args...>>
{
typedef std::tuple<T, Args...> type;
};
template <typename> struct Unravel;
template <typename T, template <typename> class X>
struct Unravel<X<T>>
{
typedef typename Concat<X<T>, typename Unravel<T>::type>::type type;
};
template <template <typename> class X>
struct Unravel<X<NullType>>
{
typedef std::tuple<X<NullType>> type;
};
template <typename T> struct printArgs;
template <typename T, typename ...Args>
struct printArgs<std::tuple<T, Args...>>
{
static void print() { std::cout << "Have type." << std::endl; printArgs<std::tuple<Args...>>::print(); }
};
template <typename T>
struct printArgs<std::tuple<T>>
{
static void print() { std::cout << "Have type." << std::endl; }
};
int main()
{
typedef A<B<C<NullType>>> CType;
printArgs<Unravel<CType>::type>::print();
}
It won't print anything exciting, so at the moment you just get one line per inheritance, but if you partially-specialize printArgs you can print specific information for your types.
This might work for you (if I understood the question correctly). I got it working with gcc, but think it should work even in VS2010.
void printTypeComponents(const Blank&)
{
std::cout << "composed of Blank\n";
}
template <typename T>
void printTypeComponents(const A<T>&)
{
std::cout << "composed of A\n";
printTypeComponents(T());
}
template <typename T>
void printTypeComponents(const B<T>&)
{
std::cout << "composed of B\n";
printTypeComponents(T());
}
template <typename T>
void printTypeComponents(const C<T>&)
{
std::cout << "composed of C\n";
printTypeComponents(T());
}
The advantage is that you do not need any typedefs inside the classes. If you want, you can put the logic inside printTypeComponentsImpl (or something like that) and have printTypeComponents delegate to that function.
You can avoid creating the temporaries, but since you cannot partially specialize functions, you'll have to move everything inside a struct and use that. If you want, I can put code example here.
edit: You could actually automate it a little bit with typeid(x).name(), provided you can extract the name of class template from it (named getTemplateName here).
template <template <typename> class T, typename U>
void printTypeComponents(const T<U>&)
{
std::cout
<< "composed of "
<< getTemplateName(typeid(T<DummyClass>).name())
<< '\n';
printTypeComponents(U());
}
For those interested, here's gcc specific example.