Template Classes with Specialized Designers

Consider the following contrived example of defining an array template:

template <typename t, unsigned int n> class TBase
{
protected:
    t m_Data[n];

    //...
};

template <typename t, unsigned int n> class TDerived : public TBase<t, n>
{
    TDerived()
    {
    }
};

I can specialize this type to provide a non-default constructor for an array of length 2 as follows:

template <typename t> class TDerived<t, 2> : public TBase<t, 2>
{
public:
    TDerived(const t& x0, const t& x1)
    {
        m_Data[0] = x0;
        m_Data[1] = x1;
    }
};

int main()
{
    TDerived<float, 2> Array2D_A(2.0f, 3.0f); //uses specialised constructor
    TDerived<float, 3> Array3D_A;             //uses default constructor

    return 0;
}

Is there any other way to create a class that has different constructor parameters, limited by template parameters at compile time, without requiring full class specialization for each variant?

In other words, is there any way that I can have specialized constructors in a class TBasewithout the need for an intermediate stage of creation TDerivedwhile maintaining functionality TBase?

+5
5

, , . , , -, . - ?

template <typename T, int N> class Foo
{
    Foo(); // general
    template <typename U> Foo<U, 2>(); // specialized, NOT REAL CODE
};

. . : , , - . :

template <typename  T> class Bar
{
  void somefunction(const T&);
};

template <> class Bar<int>
{
  double baz(char, int);
};

Bar<T>::somefunction() T, , T int, Bar<int> - .

template <> class Bar<double> : public Zip {}; - !

, specializations , , - . ( , . @Alf answer.)

+2

:

  • (.. "..." ), n , . , .

  • , , : vector(2.0f)(3.0f). -, , . , , .

+1

,

#include <stdio.h>

template< class Type >
struct Foo
{
    void bar() const
    { printf( "Single bar.\n" ); }
};

template<>
void Foo< double >::bar() const
{ printf( "double bar.\n" ); }

int main()
{
    Foo<int>().bar();
    Foo<double>().bar();
}

, .

, .

, .

hth.,

+1

- , - . .

( ). , , n = 2, t = int or double, .

template<>
TDerived<int,2>::TDerived()
{
  //...
}
template<>
TDerived<double,2>::TDerived()
{
  //...
}

..

[: MSVC, , ; :

template<typename t>
TDerived<t,2>::TDerived()
{
  //...
}

, .]

+1

static_assert (BOOST_STATIC_ASSERT ++ 0x) . , .

template<typename T, unsigned int n>
struct Foo {
  Foo(const T& x) { static_assert(n == 1, "Mooh!"); }
  Foo(const T& x1, const T& x2) { static_assert(n == 2, "Mooh!"); }
};

"" .

template<typename T, unsigned int n>
struct Foo {
  Foo(...) { 
    va_list ap;
    va_start(ap, n);
    for(int j=0; j < n; ++j)
      bork[j] = va_arg(ap, T);
    va_end(ap);
  }
};

++ 0x make_something, , .

template<typename... T, unsigned int n>
Foo<T, n> make_foo(T&&...) {
  // figure out the common_type of the argument list
  // to our Foo object with setters or as a friend straight to the internals
  Foo< std::common_type< T... >::type, sizeof(T) > foo;
  // recursive magic to pick the list apart and assign 
  // ...
  return foo;
}
0
source

All Articles