如何允许编译器推断出正确的返回类型以进行模板get函数
How to allow compiler to deduce correct return type for templated get function?
我有很多结构,所有结构都有一些元素:
struct myExample
{
std::string elem0;
int elem1;
};
如果我可以让以下内容工作,我可以避免大量编码。编写一个模板GET方法,该方法将索引作为模板参数并从上面的结构返回elem。
template<int idx, typename K, typename T> T get(const K&)
{
throw std::runtime_error("should not happen");
}
template<> std::string get<0, myExample, std::string>(const myExample& k)
{
return k.elem0;
}
template<> int get<1, myExample, int>(const myExample& k)
{
return k.elem1;
}
这是该示例的主要功能:
int main()
{
myExample test;
test.elem0 = "hello world";
test.elem1 = 42;
// does not work:
//std::string get0 = ::get<0>(test);
//int get1 = ::get<1>(test);
// does not work either:
//std::string get0 = ::get<0, myExample>(test);
//int get1 = ::get<1, myExample>(test);
// works:
std::string get0 = ::get<0, myExample, std::string>(test);
int get1 = ::get<1, myExample, int>(test);
std::cout<<get0<<":"<<get1<<std::endl;
return 0;
}
我想使用 ::get<0>(test)
,但是由于某种原因,编译器抱怨 call call call to to'get(myexample&amp;('即使至少要引发错误的模板函数可用,对吗?
原则上应该可以告诉编译器正确的返回类型,因为ELEM0和ELEM1的类型是在编译时定义的。
如何扩展此类似元组的结构以返回正确的类型,而无需手动写出它?
到目前为止,这与较旧的C 版本一起使用,这就是我不应该给我们自动之类的原因。没有C 11?
请在Ideone上查看示例。
您的输入非常感谢!
编译器必须在考虑专业知识之前推论所有模板参数,并且它无法以这种方式推断T
。
只需完全删除typename T
参数,而不需要。
您可能还想考虑一个更容易的选择:
template <int Index, typename T> auto get(const T &object)
{
return std::get<Index>(std::tie(object.elem0, object.elem1, object.elem2));
}
不要使用模板功能专业化,几乎总是一个坏主意。
而是使用过载和转发。
template<int idx>
using index_t = std::integral_constant<int, idx>;
// compile time error if it doesn't match
template<int i, class K>
void special_get(index_t<i>, const K&) = delete;
template<int idx, typename K>
decltype(special_get( index_t<idx>{}, std::declval<K const&>() ) )
get(const K& k) {
return special_get( index_t<idx>{}, k );
}
没有专业。
inline std::string special_get(index_t<0>, const myExample& k) {
return k.elem0;
}
inline int special_get(index_t<1>, const myExample& k) {
return k.elem1;
}
这些是special_get
的过载。选择哪一个是通过超载分辨率选择的,而不是模板专业化。
模板功能的专业化不应是解决任何问题的第一个,第二或第三选择。
我认为您有一个小错字,可能会使编译器试图解决模板感到困惑。在这两行中:
template<> int get<2, myExample, int>(const myExample& k) { return k.elem1_; }
template<> boost::gregorian::date get<2, myExample, boost::gregorian::date>(const myExample& k) { return k.elem2_; }
您的两个模板都有相同的索引,2。我认为您的意思是INT专业化。
所以我想在某些情况下,对于索引2,编译器无法在INT和日期之间做出决定。
相关文章:
- C++中是否有任何函数等同于python中字典的get函数?
- 如何将 c++ get 函数代码转换为 opencv 算法中使用的 python
- 使用"push_back"作为带有"get"函数C++的向量
- 从 unique_ptr::get 发送指针作为指针引用进入函数
- c++ 在类中声明私有的向量,但有一个 get 函数
- c++为什么ifstream get()函数返回无法识别的特殊字符
- 使用Set/Get-like方法或GetSet组合函数
- 为什么 std::get<T> 其中 T 是调用 constexpr 函数失败的结果?
- 如何在输入成员函数中使用 get()
- C++ :: 设置值函数在函数内设置,但后跟 Get 函数,设置值消失了
- 为什么 ADL 不能使用 std::get 解析为正确的函数
- 在类中使用映射并通过其他类的 get() 和 set() 函数访问值
- C++11: 如何编写一个像 Get 一样工作的模板函数<tuple>...但是收到参数包?
- get 函数返回无效值
- cin.get()函数在C 中
- 通过引用将私有类实例传递到另一个类 C++ 的"get"函数中
- 类成员函数 get 不会返回值
- ifstream 函数"get"如何改变其字符参数?
- 重载运算符()与成员函数get()
- 输入流函数get在c++中