【问题标题】:Template type could not be deduced无法推断模板类型
【发布时间】:2017-03-17 18:07:59
【问题描述】:

我有一个(简化的)函数 Foo

template<typename It, typename T>
void Foo(It begin, It end, T&& CallBar)
{
    CallBar(begin, end);
}

还有一个简化的函数Bar

template<typename It>
It Bar(It begin, It end)
{
    return begin;
}

当我通过以下方式调用这两个函数时

std::vector<int> v{ 3, 8, 2, 5, 1, 4, 7, 6 };
Foo(v.begin(), v.end(), Bar);

我得到了错误

“声明”:无法推断“标识符”的模板参数

我还需要指定什么才能使其编译?

【问题讨论】:

  • @NathanOliver:在这种情况下有点困难,因为我使用 VS2017 的测试工具来运行最后一个代码 sn-p。
  • 您可以使用通用 lambdas 来避免在 Bar 中指定模板参数:Foo(v.begin(), v.end(), [](auto begin, auto end) {return begin;});

标签: c++ templates


【解决方案1】:

这里的问题是因为Bar是一个函数模板,它不知道你想要哪个Bar。你必须告诉它使用哪个版本的Bar。一种方法是指定模板类型。你可以这样做:

Foo(v.begin(), v.end(), Bar<decltype(v.begin())>);

如果您不想指定模板类型,老实说,这有点脆弱,那么我们可以将对 Bar 的调用包装在 lambda 中。这将允许编译器为我们进行所有类型推导,这更容易维护。例如,如果您更改迭代器类型,则无需更改之前的解决方案。感谢0x499602D2 那将是

Foo(v.begin(),v.end(),[](auto b,auto e){return Bar(b,e);})

【讨论】:

  • 你也可以使用 lambda:Foo(v.begin(),v.end(),[](auto b,auto e){return Bar(b,e);})
  • @0x499602D2 如果您不介意,我想将其添加到答案中。
  • 当然可以。 :)
  • 我在更新答案的同一秒发布了类似的评论:)。使用简单的 lambda 比在 lambda 中嵌入 Bar 调用更简单。此外,必须检查编译器对通用 lambda 的支持(因为这是 c++14 功能)。
  • Couldn't struct Bar with operator() 模板也能解决问题?
【解决方案2】:

我还需要指定什么才能使其编译?

举例

template<typename It>
void Foo(It begin, It end, It(* CallBar)(It, It))
{
    CallBar(begin, end);
}

【讨论】:

    【解决方案3】:

    您可以使用template templates 来帮助解决这个问题。据我所知,它要求您将 Bar 函数包装在仿函数中。通过先放置functor模板参数,可以指定它,让迭代器类型被推导出来。

    #include <vector>
    
    // T is a type that takes a 'class' template argument
    template<template<class> class T, class It>
    void Foo(It begin, It end)
    {
        T<It>()(begin, end);
    }
    
    template<typename It>
    struct Bar
    {
        It operator()(It begin, It end)
        {
            return begin;
        }
    };
    
    int main()
    {
        std::vector<int> v{ 3, 8, 2, 5, 1, 4, 7, 6 };
        Foo<Bar>(v.begin(), v.end());
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      相关资源
      最近更新 更多