C++ 可变参数模板,递归 decltype
C++ variadic template, recursion decltype
我知道已经有很多关于这个主题的问题,但到目前为止我没有找到令人满意地回答以下问题的答复。给定以下代码。
#include <map>
template<typename T, typename K>
std::map<T, K> map()
{
return std::map<T, K>();
}
template<typename T, typename...K>
std::map<T, decltype(map<K...>())> map()
{
return std::map<T, decltype(map<K...>())>();
}
int main(int argc, char **argv)
{
std::map<int, int> m2 = map<int, int>();
std::map<int, std::map<int, int>> m3 = map<int, int, int>();
std::map<int, std::map<int, std::map<int, int>>> m4 = map<int, int, int, int>(); // <- Compile Error here
return 0;
}
对
的调用
map<int, int, int>()
应该return一个对象
std::map<int, std::map<int, int>>
这对最多三个模板参数非常有效。
如代码中所述,使用四个模板参数调用 pair 函数失败并且 g++ (5.1.0) returns 出现以下错误。
main.cpp: In function 'int main(int, char**)':
main.cpp:20:84: error: no matching function for call to 'map()'
std::map<int, std::map<int, std::map<int, int>>> m4 = map<int, int, int, int>(); // <- Compile Error here
^
main.cpp:4:20: note: candidate: template<class T, class K> std::map<T, K> map()
std::map<T, K> map()
^
main.cpp:4:20: note: template argument deduction/substitution failed:
main.cpp:20:84: error: wrong number of template arguments (4, should be 2)
std::map<int, std::map<int, std::map<int, int>>> m4 = map<int, int, int, int>(); // <- Compile Error here
^
main.cpp:10:40: note: candidate: template<class T, class ... K> std::map<T, decltype (map<K ...>())> map()
std::map<T, decltype(map<K...>())> map()
^
main.cpp:10:40: note: template argument deduction/substitution failed:
main.cpp: In substitution of 'template<class T, class ... K> std::map<T, decltype (map<K ...>())> map() [with T = int; K = {int, int, int}]':
main.cpp:20:84: required from here
main.cpp:10:35: error: no matching function for call to 'map()'
std::map<T, decltype(map<K...>())> map()
^
main.cpp:4:20: note: candidate: template<class T, class K> std::map<T, K> map()
std::map<T, K> map()
^
main.cpp:4:20: note: template argument deduction/substitution failed:
main.cpp:10:35: error: wrong number of template arguments (3, should be 2)
std::map<T, decltype(map<K...>())> map()
^
因此我的问题是:
- 这个问题与g++有关吗?
- 解决这个问题的指定方法是什么?
用类型操作类型通常更容易。
template<class K0, class K1, class...Ks>
struct my_map;
template<class K0, class K1, class...Ks>
using my_map_t = typename my_map<K0,K1,Ks...>::type;
template<class K0, class K1>
struct my_map<K0,K1>{using type=std::map<K0, K1>;};
template<class K0, class K1, class K2, class...Ks>
struct my_map<K0, K1, K2, Ks...>{
using type=std::map<K0, my_map_t<K1, K2, Ks...>>;
};
做你想做的。
如果你真的想要它作为一个函数:
template<class K0, class K1, class...Ks>
my_map_t<K0, K1, Ks...> map() { return {}; }
成功了。
一个函数在它自己的声明期间不在上下文中,所以你的 map
重载不能将自己视为 map
在它自己的 return 类型中的有效候选者。
您可以通过 ADL 解决这个问题(它自己声明的上下文和函数调用点的 ADL 都被视为查找重载),但这不是必需的。
我知道已经有很多关于这个主题的问题,但到目前为止我没有找到令人满意地回答以下问题的答复。给定以下代码。
#include <map>
template<typename T, typename K>
std::map<T, K> map()
{
return std::map<T, K>();
}
template<typename T, typename...K>
std::map<T, decltype(map<K...>())> map()
{
return std::map<T, decltype(map<K...>())>();
}
int main(int argc, char **argv)
{
std::map<int, int> m2 = map<int, int>();
std::map<int, std::map<int, int>> m3 = map<int, int, int>();
std::map<int, std::map<int, std::map<int, int>>> m4 = map<int, int, int, int>(); // <- Compile Error here
return 0;
}
对
的调用map<int, int, int>()
应该return一个对象
std::map<int, std::map<int, int>>
这对最多三个模板参数非常有效。 如代码中所述,使用四个模板参数调用 pair 函数失败并且 g++ (5.1.0) returns 出现以下错误。
main.cpp: In function 'int main(int, char**)':
main.cpp:20:84: error: no matching function for call to 'map()'
std::map<int, std::map<int, std::map<int, int>>> m4 = map<int, int, int, int>(); // <- Compile Error here
^
main.cpp:4:20: note: candidate: template<class T, class K> std::map<T, K> map()
std::map<T, K> map()
^
main.cpp:4:20: note: template argument deduction/substitution failed:
main.cpp:20:84: error: wrong number of template arguments (4, should be 2)
std::map<int, std::map<int, std::map<int, int>>> m4 = map<int, int, int, int>(); // <- Compile Error here
^
main.cpp:10:40: note: candidate: template<class T, class ... K> std::map<T, decltype (map<K ...>())> map()
std::map<T, decltype(map<K...>())> map()
^
main.cpp:10:40: note: template argument deduction/substitution failed:
main.cpp: In substitution of 'template<class T, class ... K> std::map<T, decltype (map<K ...>())> map() [with T = int; K = {int, int, int}]':
main.cpp:20:84: required from here
main.cpp:10:35: error: no matching function for call to 'map()'
std::map<T, decltype(map<K...>())> map()
^
main.cpp:4:20: note: candidate: template<class T, class K> std::map<T, K> map()
std::map<T, K> map()
^
main.cpp:4:20: note: template argument deduction/substitution failed:
main.cpp:10:35: error: wrong number of template arguments (3, should be 2)
std::map<T, decltype(map<K...>())> map()
^
因此我的问题是:
- 这个问题与g++有关吗?
- 解决这个问题的指定方法是什么?
用类型操作类型通常更容易。
template<class K0, class K1, class...Ks>
struct my_map;
template<class K0, class K1, class...Ks>
using my_map_t = typename my_map<K0,K1,Ks...>::type;
template<class K0, class K1>
struct my_map<K0,K1>{using type=std::map<K0, K1>;};
template<class K0, class K1, class K2, class...Ks>
struct my_map<K0, K1, K2, Ks...>{
using type=std::map<K0, my_map_t<K1, K2, Ks...>>;
};
做你想做的。
如果你真的想要它作为一个函数:
template<class K0, class K1, class...Ks>
my_map_t<K0, K1, Ks...> map() { return {}; }
成功了。
一个函数在它自己的声明期间不在上下文中,所以你的 map
重载不能将自己视为 map
在它自己的 return 类型中的有效候选者。
您可以通过 ADL 解决这个问题(它自己声明的上下文和函数调用点的 ADL 都被视为查找重载),但这不是必需的。