【问题标题】:Template return type deduction from lvalue?从左值中扣除模板返回类型?
【发布时间】:2015-12-09 20:14:22
【问题描述】:

这可能是一个愚蠢的问题,但我还是想澄清一下。假设我有一个这样的模板函数:

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

将值作为T 从存储在key 下的内部存储返回(并且可能已经作为类型T)。

现在为了使用这个我需要在函数调用中指定模板返回类型T,例如:

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

而我想要它做的是从上下文中推断出模板参数,特别是 lvalue,如下所示:

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

但我猜这是不可能的,但我对为什么很模糊。我知道使用auto 会使编译器无法推断出模板类型,但为什么也会这样呢?

【问题讨论】:

  • 模板实例化只能从给定模板化对象(在这种情况下为函数)的参数中推断出它的参数,所以不,变量类型在推断中并不重要,你要么必须证明虚拟参数像在倒数第二个脚本代码中那样对其进行函数或硬编码。
  • 直截了当的回答,谢谢。您是否愿意将其重新发布为答案,以便我接受?
  • 可以通过返回一个具有template&lt;class T&gt; operator T() const; 转换函数的代理对象来提供类似的东西。该转换函数可以推导出类型T,因为需要在代理对象的类型和int value 之间进行转换。当然,这与auto 不同,因为它只会存储代理对象(可以使代理对象不可复制和不可移动,但auto&amp;&amp;auto const&amp; 仍然有效)。
  • @dyp 这真是个有趣的主意!我刚刚对其进行了测试,它就像一个魅力。由于我将只在有限数量的类型上使用它,我什至可以完全摆脱模板,只需为我需要的每种类型拼出 operator() 重载。这确实是一个不错的选择。我想知道代理对象的开销是否值得,但这是另一个问题。

标签: c++ templates


【解决方案1】:

模板实例化只能从给定模板化对象(在这种情况下为函数)的参数推断其参数,所以不,变量类型在推断时无关紧要,您要么必须向函数提供类型为 T 的虚拟参数,要么像在倒数第二个脚本代码中那样对其进行硬编码 (getValue&lt;int&gt;(...))。

使用 cmets 中提供的类型推断有一个可能的解决方法:

#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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-19
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    相关资源
    最近更新 更多