【发布时间】:2026-02-17 21:45:02
【问题描述】:
我正在尝试创建一个函数来序列化存储为std::any 的对象。这个想法是,对象与可以序列化它的函数一起存储在 std::any 中,然后在对象上调用该函数。
我遇到了以下问题。
#include <iostream>
#include <any>
using namespace std;
template<typename T, int (*F)(T& t)>
int _GetDataFromAny(std::any& input)
{
return F(std::any_cast<T&>(input));
}
struct MyStruct
{
int val = 69;
};
int Fun(MyStruct& str) { return str.val; }
template<typename T>
void DoStuff(T& s, int (*F)(T&))
{
auto an = make_any<T>(s);
cout << _GetDataFromAny<MyStruct, F>(an);
}
int main()
{
MyStruct s = {71};
DoStuff(s, Fun); /* does not compile */
/* Works fine */
auto an = make_any<MyStruct>(s);
cout << _GetDataFromAny<MyStruct, Fun>(an);
return 0;
}
此代码有 2 个版本,一个有 DoStuff 行,一个没有。 DoStuff 背后的想法是它可以构造 std::any 容器和适当的函数来序列化该对象,但是我无法编译 DoStuff(但是其他所有内容都可以编译)。
我得到的确切错误是:
main.cpp: In instantiation of ‘void DoStuff(T&, int (*)(T&)) [with T = MyStruct]’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',38)">main.cpp:38:19</span>: required from here
main.cpp:31:41: error: no matching function for call to ‘_GetDataFromAny(std::any&)’
cout << _GetDataFromAny<MyStruct, F>(an);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
main.cpp:15:5: note: candidate: template int _GetDataFromAny(std::any&)
int _GetDataFromAny(std::any& input)
我不完全确定模板替换失败的原因。
【问题讨论】:
-
F是函数参数,不是编译时间常数。模板参数在编译时解析,因此它们必须是编译时常量。您必须将F作为模板参数传递给DoStuff。 -
请注意:
_GetDataFromAny是 reserved identifier,因为它以一个下划线开头,后跟一个大写字母。您应该选择一个不同的名称。 -
@alterigel 如何指示内部函数?因为这些是模板,所以它们必须在标题中,但我想劝阻人们不要直接调用它们。
-
@Makogan “我怎样才能指出一个内部函数?” 把它们放在你自己的
namespace中。很多项目都包含一个details嵌套命名空间,用于提供必须公开但用户应该忽略的私有实现细节。
标签: c++ templates serialization c++17