提问者:小点点

推断指向函数的指针的模板参数


对于以下代码:

#include <iostream>
#include <vector>

template <class T>
inline auto foo(const T* A)
{
    return A[0];
}

template <class T>
struct impl
{
    template <typename F>
    static auto bar(const T& A, F func)
    {
        return func(&A[0]);
    }
};

int main()
{
    std::vector<size_t> A = {2, 3, 4};
    std::cout << impl<decltype(A)>::bar(A, &foo) << std::endl;
    return 0;
}

我得到(使用C++14在macOS上使用clang)

main.cpp:23:18: error: no matching function for call to 'bar'
    std::cout << impl<decltype(A)>::bar(A, &foo) << std::endl;
                 ^~~~~~~~~~~~~~~~~~~~~~
main.cpp:14:17: note: candidate template ignored: couldn't infer template argument 'F'
    static auto bar(const T& A, F func)
                ^
1 error generated.

我的问题是:为什么?我该怎么修好呢?


共2个答案

匿名用户

foo是模板的名称,而不是函数的名称。bar需要类型,而不是模板。幸运的是,lambda表达式是将泛型函数包装成一个可以知道的对象类型并为您执行分派的快速简便的方法。那会让你

std::cout << impl<decltype(A)>::bar(A, [](const auto& var){ return foo(var); }) 
          << std::endl;

匿名用户

问题实际上来自foo,而不是implfoo是一个模板,您也会出现以下错误:

auto x = &foo;

source>:23:15: error: unable to deduce 'auto' from '& foo'
   23 |     auto x = &foo;
      |               ^~~
<source>:23:15: note:   couldn't deduce template parameter 'auto'

我并不是建议这是一个“正确”的解决方案,它只是为了说明如何在原则上获得一个指向foo的正确实例化的指针:

int main()
{
    std::vector<size_t> A = {2, 3, 4};
    std::cout << impl<decltype(A)>::bar(A,
        static_cast<size_t(*)(const decltype(A)::value_type*)>(&foo)) << std::endl;
    return 0;
}