未通过模板函数查找

时间:2011-02-09 16:26:42

标签: c++ templates language-lawyer

请考虑以下示例。

#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 );
}

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

3 个答案:

答案 0 :(得分:5)

return boo( a );

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

  

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

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

   return boo<A>(a);

标准以14.8.2.1美元计算,

  

如果未使用模板参数   任何一个函数参数   功能模板,或仅用于   一个非推断的背景,它   相应的模板参数不能   从函数调用中推导出来   template-argument必须是   明确指定

答案 1 :(得分:2)

要解决此问题,您需要在调用boo时明确指定类型,即

return boo<A>( a );

std::cout << "boo = " << boo<int>( 3 ) << std::endl;
编辑:删除了我的解释,这是垃圾,Nawaz的解释更好..

答案 2 :(得分:1)

您假设因为optional<int>具有来自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
}