作为成员的函数模板-GCC与CLANG

function template as member - GCC vs. CLANG

本文关键字:-GCC CLANG 函数模板 成员      更新时间:2023-10-16

考虑以下代码:

#include <type_traits>
#include <utility>
template <typename F>
class function
{
public:
//  using function_type = typename std::decay<F>::type;
    using function_type = F;
    function(F func)
        : function_(func)
    {
    }
private:
     function_type function_;
};
template <typename F>
function<F> make_function(F&& func)
{
    return function<F>(std::forward<F>(func));
}
double f1(double)
{
    return 0.0;
}
template <typename T>
T f2(T)
{
    return T();
}
int main()
{
    // works in both cases
    make_function(f1);
    // needs decay (with CLANG)
    make_function(f2<double>);
}

function旨在成为任何Callable的简单包装器。该代码使用GCC编译良好(我在git存储库中测试了4.9.2和7.0.0 20160427)。然而,clang(3.5.0)抱怨道:

function.cpp:17:17: error: data member instantiated with function type 'function_type' (aka 'double (double)')
         function_type function_;
                       ^
function.cpp:55:2: note: in instantiation of template class 'function<double (double)>' requested here
        make_function(f2<double>);

那么这是GCC的一个bug吗?如果变量是参数(在make_function和构造函数中),但如果它是成员变量,为什么它不起作用?衰变(commed-out)在正确的位置吗?还是应该将其移动到make_function?为什么如果我传递函数(f1)或函数模板的显式实例化(f2)会有区别?

正如评论者所指出的,这是Clang中的一个bug。

代码开始使用GCC 4.7.1(甚至可能是4.7?)和Clang 3.7进行编译:请参阅GodBolt