繁体   English   中英

用decltype()声明一个函数签名

[英]Declare a function signature with decltype()

是否可以声明一个功能bar与函数foo具有相同的签名?

int foo(int a)
{
    return 0; 
}

decltype(foo) bar
{
    return 1;
} //imaginary syntax

我认为同样适用于typedef和别名:您可以使用decltype 声明一个函数,但不能定义它:

int foo();

decltype(foo) bar;

int foo()
{
    return bar();
}

int bar() { return 0; }

被clang ++ 3.5和g ++ 4.8.1接受


[dcl.fct.def.general] / 2禁止(语法上)没有圆括号的函数的定义:

函数定义中的声明符应具有该形式

D1 ( parameter-declaration-clause ) cv-qualifier -seq opt ref-qualifier opt exception-specification opt attribute-specifier-seq opt trailing-return-type opt

如8.3.5中所述。

您可以使用可变参数模板来定义与任何函数具有相同签名的函数:

#include <iostream>

int foo(char const *blah) { return 0; }

template<typename... Args>
auto bar(Args ... args) -> decltype(foo(args...))
{
    return 1; 
}

int main() {
    std::cout << foo("test") << std::endl;
    std::cout << bar("test") << std::endl;
    return 0;
}

这也可以稍微修改以传递“foo”作为第一个模板参数,这样你就可以使用与许多不同“foo”相同的“bar”:

template<typename Func, typename... Args>
auto bar(Func f, Args ... args) -> decltype(f(args...))
{
    return 1; 
}

int baz(double d) { return 3; }

int main() {
    std::cout << bar(&foo, "test") << std::endl;
    std::cout << bar(&baz, 1.2) << std::endl;
    return 0;
}

因为你不能直接设置参数,所以你不会吝啬。 decltype(foo)确实返回foo的实际类型,因此你可以使用它来实例化一个模板traits类,然后公开返回类型和参数类型(以某种方式),然后用它来定义你的函数。

#include <stdio.h>
int sf(int, float, double, bool) {}
template <typename RV, typename... args>
RV func(args... as) {
  printf("%d %f %f %d\n", as...);
  return sf(as...);
}
template <typename RV, typename... args>
RV(*generateFunc(RV(*)(args...)))(args...) {
  return &func<RV, args...>;
}

int main() {
  decltype(sf) *f = generateFunc(sf);
  f(42, 1.0f, 12.0, true);
}

这会生成一个匹配sf签名的函数,然后将调用转发给它。

首先要记住的是,您需要将参数命名为no,不能。

foo的类型是:

int(int)

所以任何想象的声明语法如:

decltype(foo) bar { //imaginary syntax
  // can't access parameter
  return 1;
}

会有bar无法访问参数的问题。

所以你能做的最好就是@dyp建议的。

您可以做的另一件事是检查两个函数是否具有相同的签名:

static_assert(std::is_same<decltype(foo), decltype(bar)>::value, "Invalid bar signature");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM