gpt4 book ai didi

c++ - 具有类型删除的 AnyFunction 类

转载 作者:行者123 更新时间:2023-12-05 02:42:37 25 4
gpt4 key购买 nike

我想实现一个类型删除类 AnyFunction,它能够使用模板化调用运算符(返回 void)存储任何实体。例如:

struct Printer {
template<typename... Args>
void operator()(Args&&... args) {
std::cout << ... << std::forward<Args>(args);
}
};

Printer typed_printer

AnyFunction printer(typed_printer);
printer(1,2.,"3");

应该打印 1 2 3。我了解如何为具有已知调用运营商签名的实体执行此操作。例如,这有效:

struct AddFunc {
void operator()(int a, int b) {
std::cout << a << "+" << b << "=" << a + b << std::endl;
}
};


struct PrintSmthFunc {
void operator()(int a, double b, const char *c) {
std::cout << a << b << c << std::endl;
}
};


int main() {
AddFunc f1;
AnyFunction addFunc(f1);
addFunc(10, 20);
PrintSmthFunc f2;
AnyFunction printSmthFunc(f2);
printSmthFunc(1, 2., "3");
}

(这里是实现:https://godbolt.org/z/r4zq6f81G)。但是我不明白在模板化运算符的一般情况下该怎么做...我认为完全类型删除它是不可能的。

最佳答案

你不能完全按照你的要求去做。

你可以写一个 AnyPrinter 类型,但你不能写一个 AnyFunction ,除非你真的交付了一个 C++ 编译器,并将你想要存储在其中的 C++ 代码作为输入,即时编译 DLL。

DLL 的存在应该可以说明问题。假设您的 AnyFunction 是在 AnyFunction.h 中定义的。

我们将Printer编译成一个DLL PrinterCode.dll。然后我们编译一些其他类型,在 Foo.dll 中调用它 Foo

我们将 AnyPrinter 传递给 AnyFunction 并从 PrinterCode.dll 返回它。

然后您的可执行文件加载两个 dll,将 AnyFunction 传递给 Foo.dll,后者使用私有(private)类型 Foo 调用它。

知道如何打印 Foo 的代码在哪里?

可执行文件无权访问Printer 的源代码。 PrinterCode.dll 无法访问 Foo。并且 Foo.dll 无法访问 Printer

C++ 二进制文件不包含与您编写的代码等效的数据。它们包含将该代码投影到标准中指定的抽象机,然后再投影到机器代码。

其他语言可以解决这类问题,因为它们的运行时表示要么包含有关您编写的代码的所有内容,要么其通用代码不如模板强大,实际上只是自动运行时类型转换包装器。

...

现在,如果您想要类似 Java 泛型的东西,C++ 可以做到。

你可以写一个Printable,但它看起来不像C++模板代码。

struct Printer {
void operator()(std::initializer_list<PrintableRef> args) {
for(auto arg:args)
std::cout << arg;
}
};

我可以让那个工作。诀窍是我们在 PrintableRef 中完成工作。

PrintableRef 类型将内容删除为“我可以打印”。这是一个快速的:

struct PrintableRef {
void(*print)(void*, std::ostream&) = nullptr;
void* pdata = nullptr;

template<class T> requires (!std::is_same_v<std::decay_t<T>, PrintableRef>)
PrintableRef(T&& t):
print([](void* pvoid, std::ostream& os) {
os << *static_cast<decltype(std::addressof(t))>(pvoid);
}),
pdata(std::addressof(t))
{}
PrintableRef(PrintableRef const&)=default;
~PrintableRef()=default;
PrintableRef()=delete;

friend
std::ostream& operator<<(std::ostream& os, PrintableRef self) {
self.print(self.pvoid, os);
return os;
}
};

但这并没有达到 AnyFunction 的目的。

必须有人知道类型以及您想在代码中的某个位置打印它的事实。

关于c++ - 具有类型删除的 AnyFunction 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67424096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com