Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
416 views
in Technique[技术] by (71.8m points)

c++ - Template return type deduction from lvalue?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...