Шаблонная специализация с вложенным неспециализированным типом - PullRequest
0 голосов
/ 01 сентября 2011

У меня проблемы с разработкой синтаксиса для вложенной частичной специализации шаблона.Я думаю, что это все равно правильный способ выразить это.Мне нужна функция as(), которая возвращает приведенное значение.В большинстве случаев static_cast будет работать нормально, поэтому у меня есть общая версия, которая делает это, но в некоторых случаях я хочу получить конкретную.Проблема в том, что я пытаюсь вернуть два одинаковых шаблонных типа классов, используя общий typename.

template<typename ClassType>
class Generic
{
public:
    // Constructors/etc excluded

    template<typename CastType>
    CastType as() const;

private:
    ClassType m_value;
};

// Templated version:
template<typename ClassType> template<typename CastType> inline
CastType Generic<ClassType>::as<CastType>() const
{
    return static_cast<CastType>(m_value);
}

.На самом деле я не уверен на 100%, если это лучший способ сделать это, но он компилируется в GCC и, кажется, работает, так что ... в любом случае.Теперь я хочу специализироваться на другом шаблонном типе (в данном случае Eigen::Matrix<T,4,1> - но, возможно, std::vector или другой также может быть использован во времени, то есть, чтобы привести от std::vector<T> к std::list<T>), что частичноtemplated:

template<> template<typename CastType> inline
CastType Generic<Eigen::Matrix<CastType,4,1> >::as<CastType>() const
{
    return m_value[0];
}

Имеет ли это какой-то смысл?А как насчет немного другой версии, где я беру Eigen :: Matrix разных размеров и обрабатываю их специально?

template<> template<typename CastType> inline
Eigen::Matrix<CastType,3,1> Generic<Eigen::Matrix<CastType,4,1> >::as<Eigen::Matrix<CastType,3,1>() const
{
    return Eigen::Matrix<CastType,3,1>( m_value[0], m_value[1], m_value[2] );
}

Я знаю, что два приведенных выше бита кода не работают, и синтаксис, вероятно, ужасен, эточто я пытаюсь решить.Простите, если это дубликат.Я посмотрел на несколько похожих вопросов, но, похоже, ни один из них не касался этого, или я просто не видел их.

1 Ответ

0 голосов
/ 02 сентября 2011

Поскольку функция не может быть частично специализированной, вместо этого мы частично специализируем functionoid-thingy, и заставляем функцию просто использовать специализированный класс.

//generic version
template<typename ClassType, typename CastType> class As { 
public: CastType operator()(const ClassType& b)
    {return static_cast<CastType>(b);}
};
//specialization
template<> class As<int, char* > { 
public: char* operator()(const int& b)
    {throw b;} //so we know it worked
};

//generic class 
template<typename ClassType>
class Generic
{
public:
    Generic() {m_value=0;} //codepad made me put this in
    // Constructors/etc excluded

    template<typename CastType>
    CastType as() const; //as function

private:
    ClassType m_value;
};

// as function simply grabs the right "As" class and uses that
template<typename ClassType> template<typename CastType> inline
CastType Generic<ClassType>::as() const
{
    As<ClassType, CastType> impl;
    return impl(m_value);
}

//main, confirming that it compiles and runs (though I didn't check b...)
int main() {
    Generic<int> gint;
    float b = gint.as<float>();
    char* crash = gint.as<char*>();
}

код по адресу: http://codepad.org/oVgCxTMI Результаты:

необработанное исключение типа int
Отменено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...