0

Is it possible to specialize a template class by argument instead by type?

The target is to have a comfortable interface and as less as possible execution time. At the moment I know three options with different benefits.

  1. One Class with different beaviour depending on CTor Parameter
  2. Define different classes
  3. Specialized template classes

The first possibility does not fit the execution time requirement.

The second possibility does not have a nice interface, because everybody has to know that there are multiple classes with just slighly different behaviour.

The third solution is my favorit, but therefore it is needed to declare types as switches.

So I am looking for a mixture between 1. and 3.

I may be missing the correct keywords to search with.

Here the possibilities I know so far:

#include <iostream>

/**
 * opt1 -- switch at runtime
 */
class inoutslow
{
public:
    inoutslow(bool b): _switch(b)
    {
        if(_switch)
            std::cout << "slowIn1" << std::endl;
        else
            std::cout << "slowIn2" << std::endl;
    }
    ~inoutslow()
    {
        if(_switch)
            std::cout << "slowOut1" << std::endl;
        else
            std::cout << "slowOut2" << std::endl;
    }
private:
    bool _switch;
};


/**
 * opt2 -- different self defined classes
 */
class inout1
{
public:
    inout1(){std::cout << "in1" << std::endl;}
    ~inout1(){std::cout << "out1" << std::endl;}
};

class inout2
{
public:
    inout2(){std::cout << "in2" << std::endl;}
    ~inout2(){std::cout << "out2" << std::endl;}
};


/**
 * opt3 -- specialized template 
 */
struct trueType;
struct falseType;

template<typename T>
class inout
{
public:
    inout(){std::cout << "DefaultTin" << std::endl;}
    ~inout(){std::cout << "DefaultTout" << std::endl;}
};
template  <>
class inout<trueType>
{
public:
    inout(){std::cout << "Tin1" << std::endl;}
    ~inout(){std::cout << "Tout1" << std::endl;}
};
template  <>
class inout<falseType>
{
public:
    inout(){std::cout << "Tin2" << std::endl;}
    ~inout(){std::cout << "Tout2" << std::endl;}
};

int main()
{
    inoutslow i(true);
    inoutslow j(false);
    inout1 ii;
    inout2 jj;
    inout<trueType> iii;
    inout<falseType> jjj;
}

the above code in coliru

E_net4
  • 27,810
  • 13
  • 101
  • 139
florgeng
  • 856
  • 1
  • 9
  • 17
  • Sorry, but C++ does not work this way. Templates are instantiated at ***compile time***. A specialized instance of a template is constructed at ***compile time***. The actual argument to a call to a templated function isn't known until ***runtime***. Perhaps something can be finagled with a `constexpr` parameter, maybe, I haven't thought about it. – Sam Varshavchik May 25 '19 at 00:46
  • Something with constexpr is also what I had in mind, but no idea how to. But it is definately the target to do the switch at compile time, so that there is no overhead at runtime. – florgeng May 25 '19 at 00:48
  • If you have a logically-`constexpr` parameter value, that value must be known at compile-time. Therefore, instead of passing it, just use it as a template parameter. If you don't know what it is, by definition it cannot be determined at compile time, but at runtime. So basically the answer you're looking for is: use a template parameter. Either you know it at compile time, or you don't. If you do, then it can be used as a template parameter. The End. – Sam Varshavchik May 25 '19 at 00:52
  • hmm, i dont understand the anwser completely. So the usage is exactly as in the example -- so it is well known at compile time. But I am lost in how to implement that as template parameter -- would you mind to provide a few lines of code? – florgeng May 25 '19 at 01:03
  • 1
    Templates are not restricted to types. You can also write `template ` or similar. – Nico Schertler May 25 '19 at 01:04
  • @NicoSchertler now I got it, thx -- found it here https://stackoverflow.com/questions/5650199/using-template-instead-of-switch – florgeng May 25 '19 at 01:07

1 Answers1

0

Thank you guys -- for all those who might find this question instead of Using template instead of switch

/**
 * opt 4
 */
template<bool _switch>
class inoutT;
template  <>
class inoutT<true>
{
public:
    inoutT(){std::cout << "TTin1" << std::endl;}
    ~inoutT(){std::cout << "TTout1" << std::endl;}
};
template  <>
class inoutT<false>
{
public:
    inoutT(){std::cout << "TTin2" << std::endl;}
    ~inoutT(){std::cout << "TTout2" << std::endl;}
};

working sample of all (listed) possibilities

florgeng
  • 856
  • 1
  • 9
  • 17