2015-09-13 56 views
2

這可能是一個愚蠢的問題,但我希望澄清一點。可以說我有一個模板函數,如下所示:從左值模板返回類型扣除?

template<class T> T getValue(const char *key) const; 

返回從內部存儲在那裏存儲key下(且可能爲T型的話)的值作爲T

現在爲了使用這個我需要在函數調用指定模板返回類型T,例如:

int value = getValue<int>("myKey"); 

而我希望它做的是從上下文推斷模板參數,特別是lvalue像這樣:

int value = getValue("myKey"); //getValue<int>() is instantiated with int being deduced automatically from lvalue 

,但我猜測,這是不可能的,但我是相當模糊的,爲什麼。我知道使用auto會使編譯器不可能推導出模板類型,但爲什麼這也是一樣?

+1

模板實例只能從參數推斷其參數設置爲給定的模板對象(在此功能case)所以不,變量類型在推導中並不重要,並且您必須證明函數的僞參數或硬編碼它,就像您在倒數第二個腳本代碼中所做的那樣。 – Creris

+0

直截了當的答案,謝謝。您是否願意將其重新發布爲答案,以便我可以接受它? – Resurrection

+1

,能夠通過返回具有'模板算子T()const的一個代理對象來提供類似的東西;'轉換功能。該轉換函數可以推導出'T'類型,因爲需要在代理對象的類型和'int值'之間進行轉換。這打破了'auto',當然,因爲這將只是存儲代理對象(有可能使代理對象不可複製和不可移動的,但是'汽車&&'和'汽車常量&'仍然有效)。 – dyp

回答

2

模板實例化只能從給定模板對象的參數中推導出它的參數(在本例中爲函數),所以不,變量類型在推導中無關緊要,並且您必須爲函數提供類型T的僞參數或者像在倒數第二個腳本代碼(getValue<int>(...))中那樣對其進行硬編碼。

有使用在評論中提出的類型推演可能的解決方法:

#include <iostream> 

namespace byte_read { 
    //this is a hack to deduce the type using implicit conversion 
    struct type_converter { 
     const char* buffer; 

     template<typename T> 
      operator T() { 
      std::cout << "implicit convertion from " << typeid(buffer).name() 
       << " to " << typeid(T).name() << std::endl; 
      //casting memory to the desired type 
      return static_cast<T>(*buffer); 
     } 
    }; 
    type_converter getValue(const char * buffer) { 
     //here buffer is implicitly converted to T type using the operator T() 
     return {buffer}; 
    } 

} 
using namespace byte_read; 

int main() 
{ 
    char buffer[]{0,1,0,0 //int 256 encoded 
        ,97  //char 'a' encoded 
       }; 
    //pointer to read the buffer sequentialy 
    char* pos = buffer; 
    //pointer used to count the bytes readed 
    char* last_pos = pos; 

    int int_256 = getValue(pos); 
    pos+=sizeof(int); 
    std::cout << int_256 << " bytes readed :" << pos - last_pos << std::endl; 

    last_pos = pos; 
    char char_a = getValue(pos); 
    pos+=sizeof(char); 
    std::cout << char_a << " bytes readed :" << pos - last_pos << std::endl; 

} 

,您可以嘗試here