【问题标题】:Default template argument for function ignored函数的默认模板参数被忽略
【发布时间】:2014-03-01 23:01:59
【问题描述】:
template < class A, class B, class R = A >
void addMultiplyOperation( std::function< R ( const A&, const B& ) > func )
{
    ...
}

addMultiplyOperation< float, int >( []( float a, int b ) { return a * b; } );

这会导致编译器错误:

In function 'int main(int, char**)':
error: no matching function for call to 'addMultiplyOperation(main(int, char**)::__lambda1)'
addMultiplyOperation< float, int >( []( float a, int b ) { return a * b; } );
                                                                           ^
note:   candidate is:
note:   template<class A, class B, class R> void addMultiplyOperation(std::function<R(const A&, const B&)>)
void addMultiplyOperation( std::function< R ( const A&, const B& ) > func )
     ^
note:   template argument deduction/substitution failed:
note:   'main(int, char**)::__lambda1' is not derived from 'std::function<R(const float&, const int&)>'
 addMultiplyOperation< float, int >( []( float a, int b ) { return a * b; } );
                                                                            ^

尽管 R 模板参数默认初始化为 A,我必须提供第三个参数以便编译。为了使用默认模板参数,我还需要做些什么吗?

我正在使用 g++ v4.8.1。

【问题讨论】:

    标签: c++ templates default-arguments


    【解决方案1】:

    尽管 R 模板参数默认初始化为 A,但我必须提供第三个参数才能编译。

    实际上,这与它是默认参数这一事实无关。编译器也无法推断出AB。看看这个简单的例子:

    template<class A>
    void f(function<void(A)> f) { }
    int main() {
        auto lambda = [](){};
        f(lambda);
    }
    

    你会认为这会超级简单,A 应该被推导出为void。但是不,这不能完成。在推导模板参数时,编译器不会考虑参数类型对于模板参数的每种可能组合具有哪些构造函数。一般来说,进行这种推论是很棘手的。

    现在,您只需让 addMultiplyOperation 接受 any 类型,并希望它是可调用的...

    template<class Function>
    void addMultiplyOperation(Function func) {
        // ....
    }
    

    如有必要,有一些方法可以推断出函数对象可以接受的参数类型,例如本答案中所述:Is it possible to figure out the parameter type and return type of a lambda?

    如果传入的对象实际上不是可调用的,或者采用错误数量的参数,这将导致一些令人讨厌的编译错误。现在我不确定是否有解决这个问题的好方法。 C++14 中的概念应该可以缓解其中的一些问题。

    【讨论】:

    • +1 我可以理解A 没有被推断出来,但我告诉编译器A 是什么,RA 相同。但话又说回来,我不必实现这些语言边缘情况,所以我不会抱怨......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 2020-04-11
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    相关资源
    最近更新 更多