如何存储指针以功能模板,该模板将可呼叫对象作为其参数之一
How to store pointer to function template which takes Callable object as one of its parameters
考虑以下示例:
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 {});
错误,如果您删除了一些东西,请说:
[...]
m
[...]被使用,但从未定义[-fpermissive]
因此,只需按照编译器的订单来定义:
template <class T, class C>
constexpr void (*G<T,C>::m)(T,C);
现在起作用。这是因为在C 14中,您需要从[class.static.data]添加静态constexpr数据成员的定义:
如果程序空间范围([basic.def.odr](和命名空间范围定义不包含初始化程序,则[静态数据]成员仍应在命名空间范围中定义。
。 。
由于P0386的结果,constexpr
静态数据成员的C 17不再需要。文本现在读取:
如果[静态数据]成员是用
constexpr
指定符声明的,则可以是在命名空间范围内重新编辑而没有初始化器(此用法已弃用;请参见[DEPRE.STATIC_CONSTEXPR]。/blockquote>
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 如何存储指针以功能模板,该模板将可呼叫对象作为其参数之一
- C :将对象引用作为参数给出错误:呼叫class :: function()的匹配函数
- Callee返回对象的范围W.R.T.呼叫者本地变量
- 如何在C 中提供一个可呼叫的对象访问,例如lambda
- 通过其他线程通过JNI呼叫保存的Java对象
- 在C 中没有对象的呼叫功能
- 没有适当操作员()的类型对象的呼叫
- destructor呼叫以前从未构造过的对象