C++ 如何使用typedef简化作为函数指针的tempate函数参数

C++ 如何使用typedef简化作为函数指针的tempate函数参数,c++,C++,我想通过使用typedef来表示ptr参数的类型,从而简化foo #include <iostream> template <unsigned N> int foo (int (*ptr) (const char (*)[N])) { char good[N] = "good"; return ptr(&good); } int bar (const char (*x)[5]) { std::cout << *x <&

我想通过使用
typedef
来表示
ptr
参数的类型,从而简化
foo

#include <iostream>

template <unsigned N>
int foo (int (*ptr) (const char (*)[N])) {
    char good[N] = "good";
    return ptr(&good);
}

int bar (const char (*x)[5]) {
    std::cout << *x << "\n";
    return 0;
}

int main ()
{
    return foo(bar);
}

我试着使用像helper类这样的特性。是否有合适的方法为
函数类型创建
typedef

是的,您可以使用默认模板参数:

template <unsigned N, typename T = int (*) (const char (*)[N])>
int foo (T ptr);
template <unsigned N>
using fooP = int (*) (const char (*)[N]);

template <unsigned N>
int foo (fooP<N> ptr) {
  return ptr(0);
}

int bar(const char (*p)[2]) {
  return 0;
}

int main() {
  return foo(bar);
}

实际上你可以把它做成模板

template<unsigned N, typename Func) 
int foo(Func func){ return func("good"); }

int bar(const std::string& str){ return str == "good"; }

int main(){    const int r = foo(bar); }

template所以您的基本问题是在函数调用中不推断依赖类型

假设您想在消除这些混乱的同时推断出值
N
,那么您需要的是能够从函数类型映射到值
N

template<typename Func>
struct get_N {};
template<unsigned int N>
struct get_N< int( const char(*)[N] ) > {
  typedef std::integral_constant< unsigned int, N > type;
};
template<typename Func>
using getN = typename get_N<Func>::type;

我们可以访问
foo
中的
N
,唯一可以匹配
foo
的东西(除了一些花哨的步法)是
get_N
理解的东西(通过SFINAE)。

在C++11中,您可以通过使用
关键字
获得模板typedef的大致等价物。这仍然允许从参数推断
N

template <unsigned N, typename T = int (*) (const char (*)[N])>
int foo (T ptr);
template <unsigned N>
using fooP = int (*) (const char (*)[N]);

template <unsigned N>
int foo (fooP<N> ptr) {
  return ptr(0);
}

int bar(const char (*p)[2]) {
  return 0;
}

int main() {
  return foo(bar);
}
模板
使用fooP=int(*)(常量字符(*)[N]);
模板
int foo(fooP ptr){
返回ptr(0);
}
整型条(常量字符(*p)[2]){
返回0;
}
int main(){
返回foo(bar);
}

对于默认模板参数来说,这可能是一个不好的用例。它生成
int条(int(const char(*)[3]);富(巴);编译没有任何问题。@hvd您的编译演示使用
foo(bar)
。我想让模板参数推断正常工作。@0x499602D2只需尝试
返回0
foo
中。它是否编译取决于实例化是否成功。在您的示例中,它失败了,但一般来说,它很可能成功。@jxh您不会因此得到类型推断,但为什么不改用
std::function
呢?我知道这一点,但我希望
foo()
向传入的函数传递一个指向正确数组大小的指针。见更新后的帖子。考虑<代码> n>代码>参数和<代码>脚注()/代码>的正文是不可变的。这是一个很好的解决方法。我相信积分常数是C++11。但是您的解决方案的某些版本应该可以移植到C++-03,对吗?是的。积分常数是一个非常简单的常数,它只会使
等于传入的值(它也会进行键入,但您可以执行
枚举
或其他操作)。
template <unsigned N>
using fooP = int (*) (const char (*)[N]);

template <unsigned N>
int foo (fooP<N> ptr) {
  return ptr(0);
}

int bar(const char (*p)[2]) {
  return 0;
}

int main() {
  return foo(bar);
}