2015-09-13 3 views
2

Это может быть глупый вопрос, но я хотел бы, чтобы это прояснилось. Допустим, у меня есть шаблон функции следующим образом:Возврат типа возвращаемого типа из lvalue?

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

, который возвращает значение в качестве T из внутренней памяти, где она хранится под key (и, возможно, как уже типа Т).

Теперь для того, чтобы использовать это мне нужно указать тип возвращаемого шаблона 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

Возможно получить что-то подобное, возвращая прокси-объект, у которого есть оператор 'template оператор T() const;' функция преобразования. Эта функция преобразования может выводить тип 'T', потому что должно быть преобразование между типом прокси-объекта и значением' int. Это, конечно, ломается с 'auto', так как это просто сохранит прокси-объект (возможно сделать объект-прокси невозможным и невозвратным, но' auto && 'и' auto const & 'будут по-прежнему работать). – dyp

ответ

2

Создание экземпляра шаблона может выводить только его параметры из аргументов в заданный шаблонный объект (функция в этом случае), поэтому нет, тип переменной не имеет значения при выводе, и вам либо нужно предоставить фиктивный аргумент типа T функции или hardcode, как и во втором, чтобы пропустить код сценария (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

Смежные вопросы