C++;从函数返回更精确的两个模板参数? 我很好奇,在C++中有没有办法做到这一点。假设我有一个模板向量类: template <typename T> class vector { public: vector(T a, T b, T c) : x(a), y(b), z(c) {} T x,y,z; }; 模板 类向量{ 公众: 向量(ta,tb,tc):x(a),y(b),z(c){ tx,y,z; };

C++;从函数返回更精确的两个模板参数? 我很好奇,在C++中有没有办法做到这一点。假设我有一个模板向量类: template <typename T> class vector { public: vector(T a, T b, T c) : x(a), y(b), z(c) {} T x,y,z; }; 模板 类向量{ 公众: 向量(ta,tb,tc):x(a),y(b),z(c){ tx,y,z; };,c++,templates,C++,Templates,然后我有一个模板化的加法运算符: template <typename A, typename B> vector<A> operator +(const vector<A> &a, const vector<B> &b) { return vector<A>(a.x+b.x, a.y+b.y, a.z+b.z); } 模板 向量运算符+(常数向量&a,常数向量&b){ 返回向量(a.x+b.x,a.y+b

然后我有一个模板化的加法运算符:

template <typename A, typename B> 
vector<A> operator +(const vector<A> &a, const vector<B> &b) { 
   return vector<A>(a.x+b.x, a.y+b.y, a.z+b.z); 
}
模板
向量运算符+(常数向量&a,常数向量&b){
返回向量(a.x+b.x,a.y+b.y,a.z+b.z);
}
我很好奇是否有可能修改这个操作符,使结果是A和B两种类型中的哪一种更精确,除了手动专门化它

例如:

vector<float>       + vector<double> would produce a vector<double>, 
vector<long double> + vector<float>  would produce a vector<long double>
vector+vector将生成一个向量,
向量+向量会产生一个向量

我猜C++中没有自动支持,但我想我会问。

你永远也无法完成这个:

vector+vector将生成一个向量


无需大量的欺骗或返回指向您自己设计的小控件的指针,因为
operator+
必须返回编译时已知的类型。您要求返回在运行时确定的类型。

在C++0x中,您可以说:

template <typename A, typename B> 
auto operator +(const vector<A> &a, const vector<B> &b) -> vector<decltype(a.x + b.x)>
{
    //...
}
模板

auto operator+(const vector

库的形式没有任何内置的支持,但是您可以使用条件(
?:
)操作符来实现这一点

在回答另一个问题时,Johannes Schaub发表了一篇文章,很好地总结了逻辑。有了这个模板,你应该能够写:

template <typename A, typename B>  
vector< typename promote<A, B>::type >
operator+(const vector<A> &a, const vector<B> &b) 
{     
    return vector< typename promote<A, B>::type >(a.x+b.x, a.y+b.y, a.z+b.z);  
} 
模板
vector
运算符+(常数向量和a、常数向量和b)
{     
返回向量(a.x+b.x,a.y+b.y,a.z+b.z);
} 

使用模板专门化有一种相对简单的方法可以做到这一点

 template< typename A >
 struct TypePrecision {
    static const int precisionLevel;
 };

 template< typename A >
 const int TypePrecision< A >::precisionLevel = 0;


 template<>
 struct TypePrecision< float > {
    static const int precisionLevel;
 };
template<>
 struct TypePrecision< long float > {
    static const int precisionLevel;
 };
  template<>
 struct TypePrecision< double > {
    static const int precisionLevel;
 };
template<>
 struct TypePrecision< long double > {
    static const int precisionLevel;
 };

 template<>
 const int TypePrecision< float >::precisionLevel = 1;
 template<>
 const int TypePrecision< long float >::precisionLevel = 2;
 template<>
 const int TypePrecision< double >::precisionLevel = 3;
 template<>
 const int TypePrecision< long double >::precisionLevel = 4;
模板
结构类型精度{
静态常数精度级;
};
模板
const int TypePrecision::precisionLevel=0;
模板
结构类型精度{
静态常数精度级;
};
模板
结构类型精度<长浮点>{
静态常数精度级;
};
模板
结构类型精度{
静态常数精度级;
};
模板
结构类型精度<长双精度>{
静态常数精度级;
};
模板
const int TypePrecision::precisionLevel=1;
模板
const int TypePrecision::precisionLevel=2;
模板
const int TypePrecision::precisionLevel=3;
模板
const int TypePrecision:精度级别=4;
然后使用它创建一个更高精度的类型

 template < typename A , typename B >
 struct HigherPrecisionType
 { 
     static const int APrecision;
     static const int BPrecision;
 };

template < typename A , typename B >
const int HigherPrecisionType< A, B >::APrecision= TypePrecision< A >::precisionLevel;

template < typename A , typename B >
const int HigherPrecisionType< A, B >::BPrecision= TypePrecision< B >::precisionLevel;
模板
结构高精度类型
{ 
静态常数精度;
静态常数int b精度;
};
模板
const int HigherPrecisionType::APrecision=TypePrecision::precisionLevel;
模板
const int HigherPrecisionType::BPrecision=TypePrecision::precisionLevel;

我不知道如何比较这些来获得专业化中的typedef和适当的typedef。但是我希望你能理解这个想法,Andrei Alexandrescu在2001年4月1日的DDJ文章中讨论了这一点

简言之,一般问题非常复杂

Andrei使用了80行支持代码,这些代码又依赖于Loki库


干杯。

通过使用函数重载,您可以在一定程度上实现您的目标。这意味着除了通用的:

template <typename A, typename B> 
vector<A> operator +(const vector<A> &a, const vector<B> &b) { 
   return vector<A>(a.x+b.x, a.y+b.y, a.z+b.z); 
}
模板
向量运算符+(常数向量&a,常数向量&b){
返回向量(a.x+b.x,a.y+b.y,a.z+b.z);
}
还可以为特定类型声明重载,然后使用这些重载,而不是一般制造的重载:

vector<double> operator +(const vector<float> &a, const vector<double> &b) { 
   return vector<double>(a.x+b.x, a.y+b.y, a.z+b.z); 
}
向量运算符+(常量向量&a,常量向量&b){
返回向量(a.x+b.x,a.y+b.y,a.z+b.z);
}

您的另一个选择是在向量模板上为所需的类型实现转换运算符。使浮点向量能够通过运算符返回双向量。

是的。以下是C++03方法:

template < typename T1, typename T2 >
struct which_return;

template < typename T >
struct which_return<T,T> { typedef std::vector<T> type; };

template <  >
struct which_return<int,double> { typedef std::vector<double> type; };

template < >
struct which_return<double,int> : which_return<int,double> {};

// etc...
template < typename T1, typename T2 >
typename which_return<T1,T2>::type operator+ (std::vector<T1> const&, std::vector<T2> const&)
{
  // ...
}
模板
返回的结构;
模板
返回{typedef std::vector type;}的结构;
模板<>
返回{typedef std::vector type;}的结构;
模板<>
结构which_return:which_return{};
//等等。。。
模板
返回的类型名称::类型运算符+(std::vector const&,std::vector const&)
{
// ...
}
显然,如果你可以,你可以用C++ 0x方式来做。

模式“类型选择”(在“现代C++设计中阅读”)可以在这里有用。
template <bool flag, typename T, typename U>
struct Select {
    typedef T Result;
};

template <typename T, typename U>
struct Select<false, T, U> {
    typedef U Result;
};

...

template <typename A, typename B> 
vector<Select<sizeof(A) > sizeof(B), A, B>::Result> operator +(const vector<A> &a, const vector<B> &b) { 
   return vector<Select<sizeof(A) > sizeof(B), A, B>::Result>(a.x+b.x, a.y+b.y, a.z+b.z); 
}
模板
结构选择{
T型结果;
};
模板
结构选择{
typedef-U结果;
};
...
模板
向量::结果>运算符+(常量向量&a,常量向量&b){
返回向量::结果>(a.x+b.x,a.y+b.y,a.z+b.z);
}

我正在选择尺寸更大的类型:

帮助器模板:

template<bool b, typename A, typename B>
struct choose_if
{
    typedef A type;
};    
template<typename A, typename B>
struct choose_if<false, A, B>
{
    typedef B type;
};
template<typename A, typename B>
struct greater 
{
    static const bool value = sizeof(A) > sizeof(B);
    typedef vector<typename choose_if<value, A, B>::type> type;
};
模板
结构选择\u如果
{
类型定义类型;
};    
模板
结构选择\u如果
{
B型;
};
模板
大结构
{
静态常数布尔值=sizeof(A)>sizeof(B);
类型定义向量类型;
};
现在使用它:

template <typename A, typename B> 
typename greater<A, B>::type operator +(const vector<A> &a, const vector<B> &b) 
{ 
    typedef typename greater<A, B>::type  type;
    return type(a.x+b.x, a.y+b.y, a.z+b.z); 
}
模板

typename greater

模板在编译时是专门化的,没有任何理由编译器不能创建一个重载来接受
向量
向量
,并返回一个
向量
。诀窍是让它做到这一点,而不为每个组合重复源代码。这种方法很有效,我已经完成了以前也用过类似的东西。你需要更多的模板胶,采用两种类型并比较它们的精度水平,以便进行“条件”类型定义,但这是非常可行的。诀窍是先进行减法,然后进行部分专业化。嗯,问题是我知道如何进行部分专业化