2014-09-18 4 views
2

Предположим, я хочу знать, является ли тип объектом Eigen, в отличие от примитива или какого-либо другого класса. Как достичь этого без фактического литья объекта?Как определить, является ли объект типом Eigen?

template <typename Derived> 
EigenBase<Derived> fun(const EigenBase<Derived>& value) 
{ 
    // This is bad, because value is now of type EigenBase<Derived> and I don't know 
    // what the original type is. 
    return value; 
} 

template <typename T> 
T fun(const T& value) 
{ 
    // This will also catch primitives and other classes. 
    return value; 
} 

Как я могу поймать только типов, которые могут быть типом, выведенными в Eigen::EigenBase<T>, фактически бросая их к этому типу?

+0

Вы можете использовать ['std :: is_base_of'] (http://en.cppreference.com/w/cpp/types/is_base_of). – juanchopanza

+0

@juanchopanza Прохладный Я не знал об этом, но какой тип я использую? Я не знаю, что такое 'Derived' в этом экземпляре ... – arman

+0

Собственно,« Как я могу уловить только типы, которые могут быть выведены по типу Eigen :: EigenBase , не наведя их на этот тип? » Это то, что вы делаете в своем первом примере. Я думаю, вам нужно переформулировать вашу проблему, потому что сейчас похоже, что вам нужно выяснить, как вернуть значение производного класса с ссылкой на его базу. – juanchopanza

ответ

1

В первой версии, тип выражения Actuel является Derived, и вы можете получить его через .derived() члена:

template <typename Derived> 
typename Derived::PlainObject fun(const EigenBase<Derived>& a_value) 
{ 
    const Derived &value(a_value.derived());  // the actual expression object 
    typename Derived::PlainObject ret;   // this is an object with storage, typically the Matrix<> type closest to Derived. 
    ret = 2*value; 
    return ret; 
} 

Более того, вы никогда не должны возвращаться по значению и, как правило, создавать объект EigenBase <>. У EigenBase нет никакого хранилища, это похоже на абстрактный базовый класс.

+0

Спасибо ggael; будет ли эта функция принудительно оценивать значение «2 *» при возврате? Если да, то как я могу вернуть по значению только выражение? – arman

+1

, тогда вы должны записать полный тип выражения, которое может стать очень сложным, или использовать C++ 11 auto. Но будьте осторожны, невозможно вернуть выражения, связанные с временными. – ggael

0
template<typebame T> 
class IsEigen 
{ 
public: 
    enum 
    { 
     value = 0; 
    } 
}; 

template<> 
class IsEigen<Eigen> 
{ 
public: 
    enum 
    { 
     value = 1; 
    } 
}; 

template<typename Derived> 
EigenBase<Derived> fun(const EigenBase<Derived>& value) 
{ 
    if(IsEigen<Derived>::value) 
    { 
     ... 
    } 
    else 
    { 
     ... 
    } 
    ... 
} 
2

Вы можете использовать SFINAE и std::is_base_of:

template <typename T> 
typename std::enable_if<std::is_base_of<EigenBase<T>, T>::value, T>::type 
fun(const T& value) 
{ 
    // This will be enabled only for class which derive from EigenBase<T>. 
    return value; 
}