Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

function template as member - GCC vs. CLANG

Tags:

c++

c++11

clang++

Consider the following code:

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

The class function is intended to be a simple wrapper for any Callable . The code compiles fine with GCC (I tested both 4.9.2 and 7.0.0 20160427 from the git repository). However, clang (3.5.0) complains:

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

So is this a bug of GCC? Why does it work if the variable is an argument (in make_function and the constructor) but not if it is a member variable? Is the decay (commmented out) in the right place or should I move it into make_function? Why does it make a difference if I pass a function (f1) or an explicit instantation of a function template (f2)?

like image 810
cschwan Avatar asked May 10 '16 11:05

cschwan


1 Answers

As commenters point out, this was a bug in Clang.

The code started compiling with GCC 4.7.1 (perhaps even 4.7?), and Clang 3.7: See it on GodBolt.

like image 58
einpoklum Avatar answered Nov 01 '22 04:11

einpoklum