Template Constraints C++

In C# we can define a generic type that imposes constraints on the types that can be used as the generic parameter. The following example illustrates the usage of generic constraints:

interface IFoo
{
}


class Foo<T> where T : IFoo
{
}

class Bar : IFoo
{
}

class Simpson
{
}

class Program
{
    static void Main(string[] args)
    {
        Foo<Bar> a = new Foo<Bar>();
        Foo<Simpson> b = new Foo<Simpson>(); // error CS0309
    }
}

Is there a way we can impose constraints for template parameters in C++.


C++0x has native support for this but I am talking about current standard C++.


If you use C++11, you can use static_assert with std::is_base_of for this purpose.

For example,

#include <type_traits>

template<typename T>
class YourClass {

    YourClass() {
        // Compile-time check
        static_assert(std::is_base_of<BaseClass, T>::value, "type parameter of this class must derive from BaseClass");

        // ...
    }
}

"Implicitly" is the correct answer. Templates effectively create a "duck typing" scenario, due to the way in which they are compiled. You can call any functions you want upon a template-typed value, and the only instantiations that will be accepted are those for which that method is defined. For example:

template <class T>
int compute_length(T *value)
{
    return value->length();
}

We can call this method on a pointer to any type which declares the length() method to return an int. Thusly:

string s = "test";
vector<int> vec;
int i = 0;

compute_length(&s);
compute_length(&vec);

...but not on a pointer to a type which does not declare length():

compute_length(&i);

This third example will not compile.

This works because C++ compiles a new version of the templatized function (or class) for each instantiation. As it performs that compilation, it makes a direct, almost macro-like substitution of the template instantiation into the code prior to type-checking. If everything still works with that template, then compilation proceeds and we eventually arrive at a result. If anything fails (like int* not declaring length()), then we get the dreaded six page template compile-time error.


As someone else has mentioned, C++0x is getting this built into the language. Until then, I'd recommend Bjarne Stroustrup's suggestions for template constraints.

Edit: Boost also has an alternative of its own.

Edit2: Looks like concepts have been removed from C++0x.


You can put a guard type on IFoo that does nothing, make sure it's there on T in Foo:

class IFoo
{
public:
    typedef int IsDerivedFromIFoo;
};

template <typename T>
class Foo<T>
{
    typedef typename T::IsDerivedFromIFoo IFooGuard;
}

Check out Boost

The Boost Concept Check Library (BCCL)

The Concept Check library allows one to add explicit statement and checking of concepts in the style of the proposed C++ language extension.