C++ 模板返回类型从左值中扣除?
这可能是一个愚蠢的问题,但我仍然希望澄清它。假设我有这样一个模板函数:C++ 模板返回类型从左值中扣除?,c++,templates,C++,Templates,这可能是一个愚蠢的问题,但我仍然希望澄清它。假设我有这样一个模板函数: template<class T> T getValue(const char *key) const; 我想让它做的是从上下文中推断模板参数,特别是lvalue,如下所示: int value = getValue("myKey"); //getValue<int>() is instantiated with int being deduced automatically from lvalue
template<class T> T getValue(const char *key) const;
我想让它做的是从上下文中推断模板参数,特别是lvalue
,如下所示:
int value = getValue("myKey"); //getValue<int>() is instantiated with int being deduced automatically from lvalue
int value=getValue(“myKey”)//getValue()实例化时,int将自动从左值推导而来
但我猜这是不可能的,但我不清楚为什么。我知道使用
auto
会使编译器无法推断模板类型,但这也是为什么?模板实例化只能从给定模板对象(本例中为函数)的参数推断其参数,因此不,在推断时变量类型无关紧要,您必须向函数提供T类型的伪参数,或者像在倒数第二个脚本代码(getValue(…)
中那样对其进行硬编码
使用注释中提供的类型推断有一种可能的解决方法:
#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;
}
#包括
名称空间字节读取{
//这是一种使用隐式转换推断类型的方法
结构类型转换器{
常量字符*缓冲区;
模板
算子T(){
std::cout模板实例化只能从给定模板对象(本例中为函数)的参数推断其参数因此,不,变量类型在推导中并不重要,您必须证明函数的伪参数,或者像在倒数第二个脚本代码中那样对其进行硬编码。答案很简单,谢谢。您是否愿意将其作为答案重新发布,以便我可以接受它?通过返回具有一个模板运算符T()const;
转换函数。该转换函数可以推断类型T
,因为代理对象的类型和int值之间需要进行转换。当然,这与auto
不同,因为这将简单地存储代理对象(可以使代理对象不可复制和不可更改,但auto&
和auto const&
仍将工作)@dyp这真是个有趣的主意!我刚刚测试过,效果非常好。因为我只打算在有限数量的类型上使用它,所以我甚至可以完全去掉模板,只需要拼出操作符()为我需要的每种类型重载。这确实是一个不错的选择。我想知道代理对象的开销是否值得,但这是另一个问题。
#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;
}