Disable construction of non fully specialized template class

Moia

I have this kind of structure for a template class.

My aim is to forbid creation of those class which not provide a full specialization:

class AbstractContainer
{
public:
   virtual ~AbstractContainer() = default;

   // declare here interface methods
};

template <class T>
class Container final : public AbstractContainer
{
public:
   Container() = delete;
};


template <>
class Container<int> : public AbstractContainer
{
public:
   Container() = default;

   explicit Container(const int& type) : AbstractContainer(), type_(type){}

private:
   int type_;
};

Everyhthing works fine

Container<int> a;     // it works
Container<int> a(5);  // it works
Container<char> a;    // does not compile

but I noticed it compiles for these case

Container<int> a(Container<char>());
Container<int> a(Container<CustomClass>());

How can I avoid this situation? I do want a copy constructor but not with the wrong type, ideally I would like to have the same issue of compile error (I could use an assert somewhere, but don't know how to set up it).

ローウ

This seems to be a C++'s most vexing parse issue:

Container<int> a(Container<char>());

This is actually just a function declaration: It declares a function a that returns a Container<int> object and takes a pointer to a function that returns Container<char> and takes nothing.

Since it is just a function declaration, it does not instantiate Container<char> at all and, therefore you are not getting any error.

You could use brace syntax instead of parenthesis, i.e.:

Container<int> a{Container<char>()};
Container<int> b(Container<char>{});
Container<int> c{Container<char>{}};

The code above does declare three objects: a, b and c.


Getting a custom error when instantiating Container<>'s primary template

You could define the following template, deferred_false, as:

template<typename>
struct deferred_false {
    static constexpr auto value = false;
};

or simply as:

#include <type_traits>
template<typename> struct deferred_false: std::false_type{};

Then, place a static_assert that uses this deferred_false<T>::value in the definition of your class template :

template<class T>
class Container final : public AbstractContainer
{
   static_assert(deferred_false<T>::value, "Trying to instantiate Container<>");
};

This way, the assertion will fail at compile time when the primary template of Container is going to be instantiated, but won't fail when the primary template is not being instantiated, since the condition of the static_assert depends on the template parameter (i.e.: T).

That is, if there is no specialization of Container for Foo and you have:

Container<Foo> a;

You will get the following compile-time error:

error: static assertion failed: Trying to instantiate Container<>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Explicit specialization of a function template for a fully specialized class template

From Dev

Specialized constructors for a template class

From Dev

Correct forward declaration of fully specialized template classes

From Dev

Template specialization within template specialized class

From Dev

Template class with template method specialized for itself

From Dev

Use generalized template class in specialized template functions

From Dev

Use generalized template class in specialized template functions

From Dev

Using a partial template class as a specialized template function

From Dev

Template class with template method specialized for itself

From Dev

Fully specialized overloaded method is not called when used as template default parameter

From Dev

Dynamic linking fails on CLang for constexpr static member of fully specialized template

From Dev

why Specialized template class need forward declaration?

From Dev

template class with a single method specialized in C++

From Dev

using declaration of a specialized variadic template class

From Dev

using declaration of a specialized variadic template class

From Dev

Defining conversion operator for specialized template class only

From Dev

Out-of-class definition of function of specialized inner class template?

From Dev

Passing a derived class to a template function specialized with base class

From Dev

Passing a derived class to a template function specialized with base class

From Dev

C++ specialized template class for a given type list

From Dev

non template function in a template class

From Dev

Calling a specialized template function, when there is also a non-template function in C++

From Dev

template metaprogramming to disable functionality of a class

From Dev

Template specialization on a non template method in a template class

From Dev

Template specialization on a non template method in a template class

From Dev

template class variable as member of a non template class

From Dev

How do I define a template member function outside of a full specialized template class's definition?

From Dev

How do I define a template member function outside of a full specialized template class's definition?

From Dev

Specialized template function vs specialized template function without template keyword

Related Related

  1. 1

    Explicit specialization of a function template for a fully specialized class template

  2. 2

    Specialized constructors for a template class

  3. 3

    Correct forward declaration of fully specialized template classes

  4. 4

    Template specialization within template specialized class

  5. 5

    Template class with template method specialized for itself

  6. 6

    Use generalized template class in specialized template functions

  7. 7

    Use generalized template class in specialized template functions

  8. 8

    Using a partial template class as a specialized template function

  9. 9

    Template class with template method specialized for itself

  10. 10

    Fully specialized overloaded method is not called when used as template default parameter

  11. 11

    Dynamic linking fails on CLang for constexpr static member of fully specialized template

  12. 12

    why Specialized template class need forward declaration?

  13. 13

    template class with a single method specialized in C++

  14. 14

    using declaration of a specialized variadic template class

  15. 15

    using declaration of a specialized variadic template class

  16. 16

    Defining conversion operator for specialized template class only

  17. 17

    Out-of-class definition of function of specialized inner class template?

  18. 18

    Passing a derived class to a template function specialized with base class

  19. 19

    Passing a derived class to a template function specialized with base class

  20. 20

    C++ specialized template class for a given type list

  21. 21

    non template function in a template class

  22. 22

    Calling a specialized template function, when there is also a non-template function in C++

  23. 23

    template metaprogramming to disable functionality of a class

  24. 24

    Template specialization on a non template method in a template class

  25. 25

    Template specialization on a non template method in a template class

  26. 26

    template class variable as member of a non template class

  27. 27

    How do I define a template member function outside of a full specialized template class's definition?

  28. 28

    How do I define a template member function outside of a full specialized template class's definition?

  29. 29

    Specialized template function vs specialized template function without template keyword

HotTag

Archive