亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用帶有可變參數模板函數的decltype的尾隨返回類型

使用帶有可變參數模板函數的decltype的尾隨返回類型

C++
拉風的咖菲貓 2019-11-03 08:04:37
我想編寫一個簡單的加法器(用于傻笑),將每個參數加起來并返回具有適當類型的和。目前,我有這個:#include <iostream>using namespace std;template <class T>T sum(const T& in){   return in;}template <class T, class... P>auto sum(const T& t, const P&... p) -> decltype(t + sum(p...)){   return t + sum(p...);}int main(){   cout << sum(5, 10.0, 22.2) << endl;}在GCC 4.5.1上,這似乎可以很好地用于2個參數,例如sum(2,5.5)返回7.5。但是,使用了比這更多的參數,我得到的錯誤是尚未定義sum()。如果我這樣聲明sum():template <class T, class P...>T sum(const T& t, const P&... p);然后它適用于任意數量的參數,但是sum(2,5.5)將返回整數7,這不是我期望的。對于兩個以上的參數,我認為decltype()必須進行某種遞歸才能得出t + sum(p ...)的類型。這是合法的C ++ 0x嗎?還是decltype()僅適用于非變量聲明?如果是這樣,您將如何編寫這樣的函數?
查看完整描述

3 回答

?
慕村9548890

TA貢獻1884條經驗 獲得超4個贊

我認為問題在于,可變參數函數模板僅在您指定其返回類型后才視為已聲明,因此sumin decltype永遠無法引用可變參數函數模板本身。但是我不確定這是GCC錯誤還是C ++ 0x根本不允許這樣做。我的猜測是C ++ 0x不允許在->decltype(expr)零件中進行“遞歸”調用。


作為解決方法,我們可以避免->decltype(expr)使用自定義特征類進行此“遞歸”調用:


#include <iostream>

#include <type_traits>

using namespace std;


template<class T> typename std::add_rvalue_reference<T>::type val();


template<class T> struct id{typedef T type;};


template<class T, class... P> struct sum_type;

template<class T> struct sum_type<T> : id<T> {};

template<class T, class U, class... P> struct sum_type<T,U,P...>

: sum_type< decltype( val<const T&>() + val<const U&>() ), P... > {};

這樣,我們可以將decltype您的程序替換為typename sum_type<T,P...>::type并進行編譯。


編輯:由于這實際上返回,decltype((a+b)+c)而不是decltype(a+(b+c))更接近于您使用加法的方式,因此您可以用此替換最后一個專業化:


template<class T, class U, class... P> struct sum_type<T,U,P...>

: id<decltype(

      val<T>()

    + val<typename sum_type<U,P...>::type>()

)>{};



查看完整回答
反對 回復 2019-11-04
?
holdtom

TA貢獻1805條經驗 獲得超10個贊

C ++ 14的解決方案:


template <class T, class... P>

auto sum(const T& t, const P&... p){

    return t + sum(p...);

}

返回類型自動扣除。



查看完整回答
反對 回復 2019-11-04
?
偶然的你

TA貢獻1841條經驗 獲得超3個贊

顯然,您不能以遞歸方式使用decltype(至少目前是這樣,也許他們會解決它)


您可以使用模板結構來確定總和的類型


看起來很丑但是可以用


#include <iostream>

using namespace std;



template<typename... T>

struct TypeOfSum;


template<typename T>

struct TypeOfSum<T> {

    typedef T       type;

};


template<typename T, typename... P>

struct TypeOfSum<T,P...> {

    typedef decltype(T() + typename TypeOfSum<P...>::type())        type;

};




template <class T>

T sum(const T& in)

{

   return in;

}


template <class T, class... P>

typename TypeOfSum<T,P...>::type sum(const T& t, const P&... p)

{

   return t + sum(p...);

}


int main()

{

   cout << sum(5, 10.0, 22.2) << endl;

}



查看完整回答
反對 回復 2019-11-04
  • 3 回答
  • 0 關注
  • 495 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號