2014-11-02 113 views
4

我对模板有一个好奇的问题,我试图在 模板类和“float/double/int”类型之间做一个基本加法运算。这是非常基本的,但如果我这样做:运算符+和浮点型参数

template<class T> 
class toto{ 
    T a; 
}; 

template<class T> 
toto<T> operator+(toto<T> const&, T&){ 
    std::cout << "hello " <<std::endl; 
} 

int main(){ 
    toto<float> t; 
    toto<float> d = t +2.3; 
} 

它不会编译,因为2.3被认为是双倍,它不符合签名。我可以为我的运营商使用第二个模板参数

template<class T, class D> 
toto<T> operator+(toto<T> const&, D&){ 
    std::cout << "hello " <<std::endl; 
} 

它编译,正确执行但过于危险D可以是一切。另一种方法是使用float,double或int(O_O)创建不同的签名。升压:: enable_if看来我的解决方案,但在我的文档阅读:

template <class T> 
T foo(T t,typename enable_if<boost::is_arithmetic<T> >::type* dummy = 0); 

应用此方法来操作*行得不行的,因为编译器会抱怨默认参数是被禁止的。

有什么建议吗?

干杯,

++吨

+2

'TOTO d = T + 2.3f;' – NaCl 2014-11-02 23:15:24

+0

谢谢你,我已经测试它,它的工作原理很不幸,这“代码”是一个非常大的抽象。如果我必须改变我所有的2.3 - > 2.3f,这将需要永远,我有数千行检查/更改。到现在为止,我拥有double/float和int的签名,它可以工作,但不够高雅。 – 2014-11-03 08:12:17

+0

正则表达式如何? – NaCl 2014-11-03 14:19:44

回答

5

使用用于第二参数的非推导出上下文。和一个const-引用作为参数,允许rvalues。

template <typename T> struct identity {using type = T;}; 
template <typename T> 
using identity_t = typename identity<T>::type; 

template<class T> 
toto<T> operator+(toto<T> const&, identity_t<T> const&) 
{ 
    std::cout << "hello " <<std::endl; 
} 

由于无法推导调用的模板参数,所以未推导的上下文将导致扣除忽略特定参数的调用参数。在某些情况下,如同这里一样,这是所期望的,因为不再一致的扣除是不可能的。换句话说,第二个参数的类型完全取决于调用的第一个参数,而不是第二个参数(可以隐式转换)。

toto<float> d = t + 2.3; 

现在应该编译Demo

+0

谢谢,我喜欢你的解决方案。我有一个框架,我有一个密集的使用模板表达式的这个问题,与此方法,我不使用额外的模板参数。 – 2014-11-03 08:23:28

1

您可以使用enable_if这样的:

template<class T, class D, typename = typename std::enable_if<std::is_arithmetic<D>::value>::type> 
toto<T> operator+(toto<T> const&, const D&){ 
    std::cout << "hello " <<std::endl; 
    return toto<T>();   
} 

Demo

+0

谢谢,我将测试Columbo的前一个解决方案,由于我的模板表达式和大量使用的模板参数, – 2014-11-03 08:24:16

1

enable_if小号往往不会太漂亮读但其他手段感觉更糟。 我通常使用的返回值类型实现的功能,因为它位于最 前面:

#include<type_traits> 
#include<iostream> 

template<class T> 
class toto 
{ 
    T a; 
}; 

template<typename T,typename D> 
typename std::enable_if< std::is_arithmetic<D>::value 
         // && some other constraint 
         // && etc. 
    , toto<T> >::type operator+(toto<T> const&, D const&) 
{ 
    std::cout << "hello " <<std::endl; 
} 

int main() 
{ 
    toto<float> t; 
    toto<float> d = t +2.3; 
} 
+0

谢谢,但我会先使用Columbo的解决方案。 – 2014-11-03 08:24:52