2015-02-10 2 views
4

В следующем коде из Boost library:роли get_unit_value в повышающем ODEINT

template<class T , class Enabler = void > 
struct get_unit_value_impl 
{ 
    static T value(const T &t) 
    { 
     return t; 
    } 
    typedef T result_type; 
}; 

...

template<class T> 
typename detail::get_unit_value_impl<T>::result_type get_unit_value(const T &t) 
{ 
    return detail::get_unit_value_impl<T>::value(t); 
} 

Роль get_unit_value мне не ясны. Что оно делает? мы передаем ему что-то, и оно возвращает то же значение. Зачем кому-то обертывать его в структуру? Делает ли это что-либо, кроме замедления времени выполнения?

Этот код вызывается из here:

template< class Fac1 = double > 
struct rel_error 
{ 
    const Fac1 m_eps_abs , m_eps_rel , m_a_x , m_a_dxdt; 

    rel_error(Fac1 eps_abs , Fac1 eps_rel , Fac1 a_x , Fac1 a_dxdt) 
    : m_eps_abs(eps_abs) , m_eps_rel(eps_rel) , m_a_x(a_x) , m_a_dxdt(a_dxdt) { } 


    template< class T1 , class T2 , class T3 > 
    void operator()(T3 &t3 , const T1 &t1 , const T2 &t2) const 
    { 
     using std::abs; 
     set_unit_value(t3 , abs(get_unit_value(t3))/(m_eps_abs + m_eps_rel * (m_a_x * abs(get_unit_value(t1)) + m_a_dxdt * abs(get_unit_value(t2))))); 
    } 

    typedef void result_type; 
}; 
+1

Среда не должна зависеть от этого шаблона. Оптимизатор должен полностью устранить его. – headmyshoulder

ответ

2

Вы забыли скопировать одну из специализаций:

template<class T , class Enabler = void > 
struct get_unit_value_impl 
{ 
    static T value(const T &t) 
    { 
     return t; 
    } 
    typedef T result_type; 
}; 

#ifndef __CUDACC__ 
template<class Unit , class T> 
struct get_unit_value_impl< boost::units::quantity< Unit , T> > 
{ 
    static T value(const boost::units::quantity< Unit , T> &t) 
    { 
     return t.value(); 
    } 
    typedef T result_type; 
}; 
#endif 

Точка get_unit_value() должен принимать либо значение и вернуть его, или boost::unit::quantity<Unit, T> и вернуть значение. Таким образом, вызывающий абонент не нужно беспокоиться о том, если t это просто int или что-то более сложное:

int x = 7; 
quantity<length> L = 2.0*meters; 

get_unit_value(x); // 7 
get_unit_value(L); // 2.0 
+0

Большое спасибо. Теперь я понимаю цель лучше. Тем не менее это не совсем понятно. Что я понял из этого, если нет CUDA ACCelerator, то возьмите «значение» аргумента? Но если есть CUDA ACC, не делайте этого? но почему? – torbani

+0

@torbani Что я не могу сказать. Я ничего не знаю о CUDA и почему эта функция не реализована в этом случае. Я могу просто сказать, почему он существует вообще. – Barry

+0

@torbani Компилятор CUDA известен тем, что ломается при виде любого заголовка Boost; Думаю, кто-то пытался защититься от Боуста. – DanielKO