的函数模板的指针

的函数模板的指针

考虑以下示例:

template <typename T>
void f (T t) {
    std::cout << t << std::endl;
}


template <typename T>
struct F {
    static constexpr void (*m) (T) = &f;
};

和用法:
F<int>::m (10);

到现在为止还挺好。当我想存储指向带有lambda表达式的函数模板的指针时,出现问题。考虑一下这一点:
template <typename T, typename C>
void g (T t, C c) {
    std::cout << c (t) << std::endl;
}

template <typename T, typename C>
struct G {
    static constexpr void (*m) (T, C) = &g;
};

和用法:
auto l = [] (auto v) { return v; };
G<int, decltype (l)>::m (20, l);

在GCC 5.3.1上使用以下命令进行编译时:
g++-5 -std=c++14 -Wall -Wextra -Wpedantic -Werror=return-type main.cpp -o main

我有:
‘constexpr void (* const G<int, main(int, char**)::<lambda(auto:1)> >::m)(int, main(int, char**)::<lambda(auto:1)>)’, declared using local type ‘main(int, char**)::<lambda(auto:1)>’, is used but never defined [-fpermissive]

为什么会这样?

有什么方法可以使此代码起作用?

我不感兴趣的一种可能的解决方案:
struct O {
    template <typename T>
    T operator() (T v) {
        return v;
    }
};

用法:
G<int, O>::m (20, O {});

最佳答案

如果删除某些内容,该错误将显示:



因此,只需遵循编译器的命令并对其进行定义:

template <class T, class C>
constexpr void (*G<T,C>::m)(T,C);

现在就可以了。这是因为在C++ 14中,您需要从[class.static.data]添加静态constexpr数据成员的定义:



由于p0386,对于constexpr静态数据成员,在C++ 17中不再需要此方法。文字now reads:

09-10 04:07