为什么这个 `my::test` 没有推导出模板参数?
Why is this `my::test` not deduced template parameter?
我遇到了与此类似的问题:std::function and std::bind: how to load a std::bind with a function template
我没有找到任何满意的答案,但我的疑问与上述post相似(不相同)
代码:
#include <iostream>
#include <functional>
using namespace std;
namespace my {
template <typename T>
struct test;
template <typename R, typename ...Ts>
struct test<R(Ts...)>{
test(R(*func)(Ts...)){
//None content, only test
}
};
}
void install1(my::test<int(int, int)> func)
{
}
template <typename R, typename ...Ts>
void install2(my::test<R(Ts...)> func)
{
}
int add(int a, int b)
{
return a + b;
}
int main(int argc, char *argv[])
{
install1(add);
my::test<int(int, int)> fun = add;
install1(fun);
install2<int, int, int>(add);
return 0;
}
我注意到的问题:
- 调用install 2函数时,不能扣除参数
- 如果我在
<b>void install2</b>
中使用这段代码
template <typename R, typename A, typename B>
void install2(my::test<R(A, B)> func)
{}
install2<int, int, int>(add);
上面的代码工作正常,但如果我删除“A、B”并放入“...Ts”,程序将无法编译
在此先感谢,对于问题描述中的任何误解,我深表歉意(我使用的是google翻译)
有
template <typename R, typename ...Ts>
void install2(my::test<R(Ts...)> func)
并打电话
install2<int, int, int>(add);
您已经为参数包的第一个模板参数和两个元素提供了显式模板参数。但是包中可能还有更多元素。因此函数参数还有一个包含模板参数的类型需要推导(基本上my::test<int(int, int, Ts...)>
)。
因此模板参数推导将应用于 argument/parameter 对并且它将失败,因为您提供的函数参数没有 my::test
类型。
有
template <typename R, typename A, typename B>
void install2(const char name[], my::test<R(A, B)> func)
您已经明确地为所有模板参数提供了模板参数,因此 my::test<R(A, B)> func
将不再是推导上下文。
如问题评论中所述,install2<int, int, int>({add});
也有效,因为大括号使函数 argument/parameter 对成为 non-deduced 上下文。
如果您希望能够使用显式模板参数且不使用大括号调用函数,您可以使函数参数始终是 non-deduced 上下文,例如使用 C++20 的 std::type_identity
:
template <typename R, typename ...Ts>
void install2(std::type_identity_t<my::test<R(Ts...)>> func)
但是,如果没有显式模板参数列表,就不可能再调用它了。
您可以同时使用此版本和原始版本作为重载,将一个版本转发到另一个版本,以涵盖您在示例代码中提到的所有情况。
我遇到了与此类似的问题:std::function and std::bind: how to load a std::bind with a function template
我没有找到任何满意的答案,但我的疑问与上述post相似(不相同)
代码:
#include <iostream>
#include <functional>
using namespace std;
namespace my {
template <typename T>
struct test;
template <typename R, typename ...Ts>
struct test<R(Ts...)>{
test(R(*func)(Ts...)){
//None content, only test
}
};
}
void install1(my::test<int(int, int)> func)
{
}
template <typename R, typename ...Ts>
void install2(my::test<R(Ts...)> func)
{
}
int add(int a, int b)
{
return a + b;
}
int main(int argc, char *argv[])
{
install1(add);
my::test<int(int, int)> fun = add;
install1(fun);
install2<int, int, int>(add);
return 0;
}
我注意到的问题:
- 调用install 2函数时,不能扣除参数
- 如果我在
<b>void install2</b>
中使用这段代码template <typename R, typename A, typename B> void install2(my::test<R(A, B)> func) {} install2<int, int, int>(add);
上面的代码工作正常,但如果我删除“A、B”并放入“...Ts”,程序将无法编译
在此先感谢,对于问题描述中的任何误解,我深表歉意(我使用的是google翻译)
有
template <typename R, typename ...Ts>
void install2(my::test<R(Ts...)> func)
并打电话
install2<int, int, int>(add);
您已经为参数包的第一个模板参数和两个元素提供了显式模板参数。但是包中可能还有更多元素。因此函数参数还有一个包含模板参数的类型需要推导(基本上my::test<int(int, int, Ts...)>
)。
因此模板参数推导将应用于 argument/parameter 对并且它将失败,因为您提供的函数参数没有 my::test
类型。
有
template <typename R, typename A, typename B>
void install2(const char name[], my::test<R(A, B)> func)
您已经明确地为所有模板参数提供了模板参数,因此 my::test<R(A, B)> func
将不再是推导上下文。
如问题评论中所述,install2<int, int, int>({add});
也有效,因为大括号使函数 argument/parameter 对成为 non-deduced 上下文。
如果您希望能够使用显式模板参数且不使用大括号调用函数,您可以使函数参数始终是 non-deduced 上下文,例如使用 C++20 的 std::type_identity
:
template <typename R, typename ...Ts>
void install2(std::type_identity_t<my::test<R(Ts...)>> func)
但是,如果没有显式模板参数列表,就不可能再调用它了。
您可以同时使用此版本和原始版本作为重载,将一个版本转发到另一个版本,以涵盖您在示例代码中提到的所有情况。