gpt4 book ai didi

C++ 为中间件生成的类型提供 `operator<<` 的通用方法

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:47:05 24 4
gpt4 key购买 nike

我们使用中间件为我们生成各种编程语言(包括 C++)的类型。对于为 C++ 生成的结构,我想注入(inject)可用于各种数据转换的代码,例如输出到 std::ostream .假设我们生成了以下结构:

struct Foo {
int a;
double d;
};

假设我更改了中间件编译器以生成以下模板函数:

template<typename Visitor>
void visit( Visitor &v, const Foo &data )
{
v.visit( "a", data.a );
v.visit( "d", data.d );
}

现在我可以以各种方式使用这段代码,如果不使用它应该不会影响任何东西,例如 make std::ostream::operator<< :

struct OstreamVisitor {
OstreamVisitor( std::ostream &os ) : m_os( os ) {}

void visit( const char *name, int i ) { m_os << name << "=" << i << std::endl; }
void visit( const char *name, double d ) { m_os << name << "=" << d << std::endl; }

std::ostream &m_os;
};

std::ostream &operator<<( std::ostream &out, const Foo &data )
{
OstreamVisitor v( out );
visit( v, data );
return out;
}

有效 live example但问题是我不想写 std::ostream &operator<<对于每个结构手动如此幼稚的解决方案是写:

template<typename T>
std::ostream &operator<<( std::ostream &os, const T &t );

并使用访问者,但这会干扰其他未生成的类型。那么有没有办法制作这种仅限于生成的结构的通用函数?如果可能的话,我不想向生成的结构注入(inject)任何东西,但是使用模板类而不是模板函数就可以了。

注意:不幸的是,我不能限制生成的结构属于特定的命名空间。我的想法是这样的:

// system header
template<typename T>
struct visitable_tag;

// generated header
namespace FooNamespace {
struct Foo { ... };

template<>
struct visitable_tag<Foo> {};
}

// or maybe have tag in special namespace
namespace visitable_tag_namespace {
template<>
struct visitable_tag<FooNamespace::Foo> {};
}

然后使模板输出函数仅在此类特化退出时实例化。当然,这只是可能标记的想法,我对其他方式持开放态度,但更愿意保持原始结构不变。

最佳答案

您可以结合使用宏和 SFINAE。或者看看 Boost Hana:

http://boostorg.github.io/hana/index.html#tutorial-introspection-adapting

您可以将宏的内容保持在低级别,并在此基础上构建更高级别的代码

关于C++ 为中间件生成的类型提供 `operator<<` 的通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48194929/

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