Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template return type deduction from lvalue?

Tags:

c++

templates

This might be a silly question but I would like to have it clarified none the less. Lets say I have a template function like so:

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

that returns the value as T from internal storage where it is stored under key (and possibly as type T already).

Now in order to use this I need to specify the template return type T in the function call, for example:

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

while what I would want it to do is deduce the template argument from the context, specifically the lvalue like so:

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

but I am guessing that this is not possible but I am rather fuzzy as to why. I know using auto would make it impossible for the compiler to deduce the template type but why this is as well?

like image 920
Resurrection Avatar asked Oct 20 '22 02:10

Resurrection


1 Answers

Template instantiation can only deduce its parameters from the arguments to given templated object(function in this case) so no, the variable type does not matter in deducing, and you either have to provide dummy argument of type T to the function or hardcode it as you did in the second to last script code(getValue<int>(...)).

There is a possible workaround using type deduction presented in the comments :

#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;

}

You can try it here

like image 124
Creris Avatar answered Nov 04 '22 19:11

Creris