【问题标题】:Failing the template function lookup模板函数查找失败
【发布时间】:2011-02-09 16:26:42
【问题描述】:

考虑以下示例。

#include <iostream>
#include <boost/optional.hpp>

template < typename A >
int boo( const boost::optional< A > &a );

template < typename A >
int foo( const A &a )
{
    return boo( a );
}

template < typename A >
int boo( const boost::optional< A > & )
{
    return 3;
}


int main()
{
    std::cout << "foo = " << foo( 3 ) << std::endl;
    std::cout << "boo = " << boo( 3 ) << std::endl;
}

使用 g++ 4.3.0 编译它会引发下一个编译错误:

dfg.cpp: In function ‘int main()’:
dfg.cpp:25: error: no matching function for call to ‘boo(int)’
dfg.cpp: In function ‘int foo(const A&) [with A = int]’:
dfg.cpp:24:   instantiated from here
dfg.cpp:12: error: no matching function for call to ‘boo(const int&)’

我应该做些什么不同的事情(如果可能的话,参考 C++ 标准)? 为什么会发生,我该如何解决?

编辑

解决方法是在foo 中创建正确的类型:

template < typename A >
int foo( const A &a )
{
    const boost::optional< A > optA( a );
    return boo( optA );
}

但问题仍然存在:为什么它不是自动创建的?

【问题讨论】:

    标签: c++ templates language-lawyer


    【解决方案1】:
    return boo( a );
    

    这里a 的类型是int,并且没有名称为boo 的函数接受int 类型的参数。因此你会看到这个错误:

    dfg.cpp:25: 错误:没有匹配 调用“boo(int)”的函数

    即使int 可以隐式 转换为boost::optional&lt;int&gt;,编译器也无法从调用站点推导出boost::optional&lt;T&gt; 的模板参数。这是您明确需要将类型提及为的非推断上下文之一,

       return boo<A>(a);
    

    标准在 $14.8.2.1 中说,

    如果没有使用模板参数 a 的任何函数参数 函数模板,或仅用于 一个非推断的上下文,它的 相应的模板参数不能 从函数调用中推导出来 模板参数必须是 明确指定

    【讨论】:

    • 是的,但是应该创建 boost::optional,不是吗?
    【解决方案2】:

    要解决这个问题,你需要在调用boo时明确指定类型,即

    return boo<A>( a );
    

    std::cout << "boo = " << boo<int>( 3 ) << std::endl;
    

    编辑:删除我的解释,这是垃圾,纳瓦兹的解释更好..

    【讨论】:

      【解决方案3】:

      您假设因为 optional&lt;int&gt; 有一个来自 int 的隐式构造函数,编译器应该知道这是您尝试创建的类型。

      模板类型推论不延伸至此。

      您可以编写自己的 boo 模板,其中包含可选作为概括的模板

      template< typename A > int boo( const A& a );
      template < typename A >
      int boo( const boost::optional< A > & )
      {
          return 3;
      }
      
      template < typename A >
      int boo( const A & a )
      {
          return boo<A>(boost::optional(a)); // allows implicit conversion
      }
      

      【讨论】:

        猜你喜欢
        • 2012-02-15
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-23
        • 2019-06-22
        相关资源
        最近更新 更多