C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
Is there any way in C++ to refer to a function template while neither calling it nor supplying its template parameters?
这是我想要工作的代码:
template <class T> void Foo(T&& param);
template <class F> void CallMe(F&& func)
{
func(42);
}
int main()
{
CallMe(Foo);
}
编译器在尝试实例化CallMe
时会窒息,因为它不知道我所说的Foo
是什么意思。 当然,如果我写Foo<int>
,它会起作用,但我想避免这种情况,因为在实际代码中,模板参数可能很复杂。
我目前的解决方法是使用可调用对象而不是自由函数。 例如:
class Foo
{
public:
template <class T> void operator()(T&&);
};
这工作正常,但我相信它会让我的库的用户感到困惑。 我可以使用一些模板魔法来使第一个版本工作吗?
我可以使用一些模板魔法来使第一个版本工作吗?
但愿。我希望有一天。在这方面已经有几项建议(例如P0119和P0834(。在那之前,你能做的最好的事情就是编写一个提升宏,将你的名字变成一个调用该名字的函数对象:
#define FWD(...) std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
#define LIFT(name) [&](auto&&... args)
noexcept(noexcept(name(FWD(args)...)))
-> decltype(name(FWD(args)...))
{ return name(FWD(args)...); }
这使您可以编写:
CallMe(LIFT(Foo));
否则可以做你想要的。
可以制作一些与问题中的代码有点相似的东西,但不完全是。
函数调用:
int main()
{
CallMe(Foo);
}
需要一个对象作为参数。对象可以是函数指针、类实例、lambda 或类似的东西。它不能是未实例化的模板函数,因为它不是对象。只有实例化的函数才是对象。
正如原始问题所述,使用类似函数的对象是一种变通方法,并假设以下内容对某些用户来说太混乱了:
class Foo
{
public:
template <class T> void operator()(T&&);
};
取而代之的是,可以使用通用 lambda,它基本相同,但没有所有的样板。通用 lambda 看起来几乎像一个常规函数:
auto Foo = [](auto x)
{
std::cout << x << 'n';
};
int main()
{
CallMe(Foo);
}
我可以使用一些模板魔法来使第一个版本工作吗?
不。
函数模板的名称不是函数类型,而是函数类型的系列。如果可能的话,func
的类型将从中推导出来Foo
T
的类型将保持非推导,这是实例化Foo
所必需的。
#define RETURNS(...)
noexcept(noexcept(__VA_ARGS__))
-> decltype(__VA_ARGS__)
{ return __VA_ARGS__; }
#define OVERLOADS_OF(...)
[](auto&&...args)
RETURNS( __VA_ARGS__( decltype(args)(args)... ) )
然后
CallMe(OVERLOADS_OF(Foo));
创建一个函数对象,该对象表示名称Foo
的重载,其中包括由名为Foo
的模板函数生成的函数。
RETURNS
在其他上下文中也很有用。 @Barry有一个建议,使RETURNS(X)
类似于=> X
,至少对于lambdas。
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 是否可以获取成员函数模板参数的拥有对象?
- 如何防止用户指定函数模板参数,迫使其进行推导
- 使用用户定义的转换运算符推导函数模板参数
- 构造函数模板参数推导,其中 std::function 作为参数
- 在简单地移动参数时使用函数模板参数的优点
- 使用函数模板参数作为类模板参数?
- 函数模板参数推断使用 std::Optional 失败
- 函数模板参数包问题
- 尝试将 C++11 代码转换为 C++03 时默认函数模板参数出错
- 是否可以从指向成员函数模板参数的指针推断类类型
- 精神语法不会编译:函数模板参数错误?
- 从函数模板参数中自动推论对容器的元素类型
- 函数模板参数推导和继承
- 有人能解释一下特殊的std::函数模板参数列表语法(这个奇怪的类型(Types..))吗
- 成员函数模板参数的部分专业化
- std::函数模板参数解析
- 'Incomplete type' 为标准::函数声明指向成员的指针函数模板参数时出错
- 具有指针数据类型的非类型函数模板参数
- 从模板参数类型中推导函数模板参数