Я получаю неприятную ошибку компилятора, которую я не могу решить. Это связано со специализацией шаблона, но я не вижу, что не так ...

../../include/thread/lock_guard.inl:23: error: template-id 'lock_guard<>' for 'thread::lock_guard<thread::null_mutex>::lock_guard(thread::null_mutex&)' does not match any template declaration
../../include/thread/lock_guard.inl:23: error: invalid function declaration
../../include/thread/lock_guard.inl:29: error: template-id 'lock_guard<>' for 'thread::lock_guard<thread::null_mutex>::~lock_guard()' does not match any template declaration
../../include/thread/lock_guard.inl:29: error: invalid function declaration

Код выглядит следующим образом:

 #include "thread/mutex.hpp"

namespace thread {

    template <typename T>
    class lock_guard
    {
        public:
            lock_guard(T& lock);
            ~lock_guard();

        private:
            mutable T&  m_lock;
            mutable int m_state;
    };

    template <>
    class lock_guard<null_mutex>
    {
       public:
            lock_guard(null_mutex&);
            ~lock_guard();
    };

} //namespace

#include "thread/lock_guard.inl"

------------------------------------    

#include "thread/lock_guard.hpp"

namespace thread {

    template <typename T>
    lock_guard<T>::lock_guard(T& lock)
        : m_lock(lock),
          m_state(lock.lock())
    {
        /* do nothing */
    }

    template <typename T>
    lock_guard<T>::~lock_guard()
    {
        if(0 == m_state) 
        {
            m_lock.unlock();
        }
    }

    template <>
    lock_guard<null_mutex>::lock_guard(null_mutex&)
    {
        /* do nothing */
    }

    template <>
    lock_guard<null_mutex>::~lock_guard()
    {
        /* do nothing */
    }

} //namespace
1
Graeme 14 Янв 2011 в 20:48
Что это mutable T& m_lock; должно делать? Он не должен компилироваться.
 – 
Gene Bushuyev
14 Янв 2011 в 21:48

2 ответа

Лучший ответ

Специализация шаблона полного класса больше не является шаблоном, это обычный класс. Следовательно, вам не нужен template <> при определении его членов:

lock_guard<null_mutex>::lock_guard(null_mutex&)
{
    /* do nothing */
}

lock_guard<null_mutex>::~lock_guard()
{
    /* do nothing */
}
14
Maxim Egorushkin 14 Янв 2011 в 21:01
Правильный способ написания может быть иногда запутанным :)
 – 
Johannes Schaub - litb
14 Янв 2011 в 21:27

Возможно, это не причина ошибки, но вам не нужен код специализации в заголовочном файле.

2
Doc Brown 14 Янв 2011 в 21:07
На самом деле вы этого не ХОТИТЕ. Вы получите несколько ошибок определения, если заголовок включен более чем в одну единицу перевода.
 – 
Edward Strange
14 Янв 2011 в 21:10
Объявление специализации должно быть в заголовке, если этот заголовок включен более чем в одну единицу перевода. В противном случае это нарушит одно правило определения, поскольку другие единицы перевода не будут знать, что где-то есть специализация.
 – 
Maxim Egorushkin
14 Янв 2011 в 21:19
Я переместил реализацию в шапку к простым вещам.
 – 
Graeme
14 Янв 2011 в 21:24