2010-07-14 2 views
10

Есть ли способ достичь указанного поведения? Если есть какой-то трюк, или это можно сделать, используя черты или enable_if, пожалуйста, дайте мне знать.C++ template question

template <typename T> struct Functional { 

    T operator()() const { 

     T a(5); 

       // I want this statement to be tranformed into 
       // plain 'return;' in case T = void 
     return a; // <--- 
    } 
}; 

int main() { 

    Functional<int> a; 
    a(); 

    Functional<void> b; 
    b(); // <--- Compilation error here 
} 
+8

Вы можете вернуть 'void' выражение в функцию, возвращающую' void' так что вы все в порядке на данный момент, вы имеете большая проблема с остальной частью вашей функции. 'T a (5)' не будет работать. У вас не может быть переменной типа 'void', поэтому простой' return a; 'не будет работать. Не зная деталей шаблона вашего класса, сложно дать конкретные сведения. –

ответ

24

Просто специализируются на аннулируются:

template <typename T> struct Functional { 
    T operator()() const { 
     T a(5); 
     return a; 
    } 
}; 
template <> struct Functional<void> { 
    void operator()() const { 
    } 
}; 
3

вы могли бы использовать специализацию


template <> struct Functional<void> { 

    void operator()() const { 
    } 
}; 
1

Это должно работать

template <> struct Functional<void> //specialized for 'void' 
{ 
    void operator()() const { 

     //do something 

     return ; //optional 
    } 
}; 

EDIT:

Вы также можете написать (Simpler подход)

T operator()() const { 

    return T(5); // static_cast<> not even required 
} 
0

Есть большие проблемы с этим кодом, чем кажется на первый взгляд. Например, если вы должны переслать возвращаемое значение Functional в другую функцию, тогда вы можете не просто специфицировать Functional для void - вся партия должна быть указана для void, так как если у вас есть функция, которая принимает значение void, вы можете Не передавайте это пустое выражение. И, конечно, вы не можете создавать переменные с void и т. П. В целом, проще сказать, что void является незаконным, чем пытаться справиться с ним.

Есть и другие ответы, которые уже имеют явный ответ специализации.

10

Просто скажите следующее. Он работает отлично с T быть void и эквивалентен коду вы показали

T operator()() const { 
    return static_cast<T>(5); 
} 
+3

+1: Я не думаю, что большинство людей знают, что вы можете «возвращать» выражение типа «void» из функции с возвращаемым типом 'void'. –

+0

@Johannes: Требуется ли 'static_cast <>'? Вместо этого можно использовать 'T operator()() const {return T (t)}'. –

+0

@Prasoon Saurav: выражение e может быть явно преобразовано в тип T, используя static_cast формы static_cast (e), если декларация «T t (e);» хорошо сформирована для некоторой изобретенной временной переменной t (8.5). Таким образом, оба они одинаковы. Конечно, вы не можете сделать (void v (5)), поэтому я предполагаю, что стандарт имеет явное примечание о преобразовании в void (в static_cast). Мне нравится static_cast из-за его очевидности – Chubsdad