以下代码无法与G ++一起编译(尽管我认为应该如此):

#include <iostream>

template <unsigned N>
struct foo_traits {
    typedef const char ArrayArg[N];
    typedef int Function (ArrayArg *);
};

template <unsigned N>
int foo (typename foo_traits<N>::Function *ptr) {
    return ptr(&"good");
}

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

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


我用GCC 4.4到4.7进行了检查,但模板参数推导失败。使用4.7.1:

prog.cpp: In function ‘int main()’:
prog.cpp:21:19: error: no matching function for call to ‘foo(int (&)(const char (*)[5]))’
prog.cpp:21:19: note: candidate is:
prog.cpp:10:5: note: template<unsigned int N> int foo(typename foo_traits<N>::Function*)
prog.cpp:10:5: note:   template argument deduction/substitution failed:
prog.cpp:21:19: note:   couldn't deduce template parameter ‘N’


如果我使用显式模板参数(即foo<5>(bar)),则可以正常编译。如果我使用不带typedef的代码版本,则可以正常编译:

#include <iostream>

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

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

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


是否应该编译失败的代码(即我犯了一个愚蠢的错误)?

最佳答案

int foo(typename foo_traits<N>::Function *ptr);


签名使它成为不可扣除的上下文,因此您必须包括模板参数,以便知道值N,因此也要知道指针ptr的类型。

您的第二个示例可以编译,因为可以推断出通过bar签名的类型。

关于c++ - 数组特征导致模板参数推导失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17033009/

10-11 18:02