Template specialization for a class member function in order to not use increment operator on bool

Markus Iser

In my application I use a class to flag elements that are inidicated by positive numbers (see code below). The template parameter of class Stamp is usually an unsigned integer. The advantage of flagging with a counter is, that clear() usually executes fast on huge vectors, as one increment of the counter invalidates all flags. Currently, only in my unit tests, I use boolean as template argument. Using boolean comes closest to the naive implementation of flagging numbers. But the increment operator for boolean is deprecated and will soon vanish from the standard and the compiler complains already about deprecation (not knowing that the part it's complaining about wouldn't even be executed in case of boolean). How would you specialize method clear() for the boolean case? I could not get it right, I tried it by just adding the the following definition.

template<>
void Stamp<bool>::clear() {
    std::fill(stamped.begin(), stamped.end(), false);
}

Now the compiler complains about multiple definitions of clear(). How is template specialization done right in that case. And what other possibilities do I have to fix this class in modern c++?

template <class T> class Stamp {
private:
    std::vector<T> stamped;
    T stamp;

public:
    Stamp(unsigned int size) {
        stamped.resize(size, std::numeric_limits<T>::min());
        stamp = std::numeric_limits<T>::min();
    }

    ~Stamp() { }

    void clear() {
        if (stamp < std::numeric_limits<T>::max()) {
            stamp++;
        }
        else {
            std::fill(stamped.begin(), stamped.end(), std::numeric_limits<T>::min());
            stamp = std::numeric_limits<T>::min() + 1;
        }
    }

    void unset(unsigned int index) {
        assert(index < stamped.size());
        stamped[index] = std::numeric_limits<T>::min();
    }

    void set(unsigned int index) {
        assert(index < stamped.size());
        stamped[index] = stamp;
    }

    bool isStamped(unsigned int index) const {
        return stamped[index] == stamp;
    }
};

EDIT: Using the answer of @Constructor I could come up with a method specialization by adding another definition of clear() to the header like this:

template<>
inline void Stamp<bool>::clear() {
    std::fill(stamped.begin(), stamped.end(), false);
    stamp = true;
}

This is kind of ugly but it actually works. Neither compiler nor tests choke on it.

Constructor

The full (or explicit) function template specialization is not a template. So you should treat it like a normal function.

There are two possibilities not to violate ODR (One Definition Rule) when you are working with functions or methods of classes:

1) place the declaration of the function/method in a header file and its definition in some cpp file:

// Stamp.h

template<>
void Stamp<bool>::clear();

// Stamp.cpp

template<>
void Stamp<bool>::clear()
{
    std::fill(stamped.begin(), stamped.end(), false);
    stamp = true;
}

2) mark it as inline and place its definition in your header file:

// Stamp.h

template<>
inline void Stamp<bool>::clear()
{
    std::fill(stamped.begin(), stamped.end(), false);
    stamp = true;
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Specialization of member function of class template

template class - member function specialization

Template member function specialization in a template class

Partial specialization of a class template member function

Class template member specialization

Specialization of member function template after instantiation error, and order of member functions

Template member specialization in template class

Specialization of a template member function of a template class in GCC 7

specialization of class member of a template class

No class template specialization for array of bool?

c++ call template class specialization member function

How make template member function specialization from inherited class?

Class template specialization that changes only one member function

explicit specialization of a function template (which is a member of a class template) produces "partial specialization is not allowed" error, why?

Template function specialization for template class

specialization of member function of templated class

Using member class template specialization in the class

Template member function specialization of a templated class without specifying the class template parameter

something confusing about class template partial specialization & class member specialization

Class Template Specialization for one Function

Specialization template class with templated function

Correct use of template with a class member function

Cannot use a member typedef of one class as a template parameter in a template specialization definition

Explicit template specialization cannot have a storage class - member method specialization

Explicit specialization of member function template in source file

Partial specialization of variadic template member function

Definition of C++ template specialization member function

Explicit specialization of member function with variadic template arguments

Template operator specialization from another class