gpt4 book ai didi

c++ - 很难确定 std::map 的正确值类型

转载 作者:行者123 更新时间:2023-11-30 04:58:16 26 4
gpt4 key购买 nike

附录:

让我简化我的问题,一次尝试这一步,因为我觉得我对我想要实现的目标造成了太多的困惑。

请注意,我使用的是 C++11,我认为在使用 PHP-CPP 库时我一定会使用它。但是,由于我是一个完全的初学者,我什至不确定这一点。

我的最终目标是“简单地”创建一个可以包含模板 Php::Class任何值的 map 。返回。但是让我们从尝试一个具体的开始,例如 Php::Class<Animal::Mammal> .

首先,我在命名空间 Animal 中创建一个类称为 Mammal ,从 Php::Base 延伸(当你想使用 PHP-CPP 将一个类导出到 PHP 时,它需要扩展 Php::Base ):

namespace Animal {
class Mammal : public Php::Base { /* left out for brevity */ }
}

然后,为了简单起见,让我尝试在 get_module() 中创建一个 map 现在尝试在其中添加一个元素:

extern "C"
{
PHPCPP_EXPORT void *get_module() {
// create the map
std::map<std::string, Php::Class<Animal::Mammal>> classMap;

// create the thing (at this point I just don't know what the actual return type is anymore) that will be exported later on.
Php::Class<Animal::Mammal> mammal( "Mammal" );

// try to add this "thing" to the map:
classMap[ "Animal::Mammal" ] = mammal;

/* left out for brevity */
}

这导致:

error: use of deleted function ‘Php::Class<Animal::Mammal>&
Php::Class<Animal::Mammal>::operator=(const Php::Class<Animal::Mammal>&)’

当我尝试时:

// require a pointer
std::map<std::string, Php::Class<Animal::Mammal>*> classMap;

classMap[ "Animal::Mammal" ] = *mammal;

这导致:

error: no match for ‘operator*’ (operand type is ‘Php::Class<Animal::Mammal>’)

我也尝试过很多其他的东西,但似乎没有什么能让我把模板 Php::Class创建到 map 中。在这一点上,我正在拔头发。我错过了什么?

可能是模板 Php::Class创建一些根本无法放入 map 的东西?我如何找出模板 Php::Class 的内容?实际创造?


原始问题:

虽然我对 C++ 有一些粗略的了解,但我对使用它进行实际编程还是个新手。

我正在尝试使用 PHP-CPP 开发一个 PHP 扩展.使用此库,您可以定义 C++ 类并将它们导出为 PHP 类。 Their documentation几乎只显示examples您在其中导出这些类和方法的主要位置 get_module()功能。

但是,由于这很快就会变得相当困惑,因此我想将此逻辑移至靠近各个类的位置。所以,我为此创建了一个模板函数:

namespace Animal
{
template<typename T>
void addToExtension( Php::Extension &extension, Php::Namespace &ns, ClassMap &map ) { }
}

然后我专注于类似的东西:

namespace Animal
{
class Mammal : public Php::Base
{
};

template<>
inline void addToExtension<Mammal>( Php::Extension &extension, Php::Namespace &ns, ClassMap &map ) {
Php::Class<Mammal> clss( "Mammal" );

// this is where I'm having extreme difficulty with
map[ "Animal::Mammal" ] = clss;

// add class to namespace
ns.add( std::move( clss ) );
}
}

...并在 get_module() 中然后我这样做:

PHPCPP_EXPORT void *get_module() {
static Php::Extension extension( "animals", "0.1" );

Php::Namespace ns( "Animal" );

Animal::ClassMap classMap;

Animal::addToExtension<Animal::Mammal>( extension, ns, classMap );
Animal::addToExtension<Animal::Dog>( extension, ns, classMap );
Animal::addToExtension<Animal::Cat>( extension, ns, classMap );
etc...

extension.add( std::move( ns ) );

return extension;
}

如您所见,我想将每个单独的类添加到 Animal::ClassMap map 也是如此,因为我想在后续类需要从它们扩展时使用它们(即导出到 PHP):

// for instance, something like (not sure yet, if this is actually possible)
clss.extends( map[ "Animal::Mammal" ] );

但这正是我遇到的极大困难。我试图定义 Animal::ClassMap以各种方式:

namespace Animal
{
// some examples of what I've tried:
typedef std::map<std::string, Php::Class> ClassMap;
typedef std::map<std::string, Php::Class*> ClassMap;
typedef std::map<std::string, Php::Base> ClassMap;
typedef std::map<std::string, Php::Base*> ClassMap;
typedef std::map<std::string, Php::ClassBase> ClassMap;
typedef std::map<std::string, Php::ClassBase*> ClassMap;
typedef std::map<std::string, Php::Class<Php::Base>> ClassMap;
typedef std::map<std::string, Php::Class<Php::Base>*> ClassMap;
typedef std::map<std::string, std::shared_ptr<Php::Class>> ClassMap;
// etc., etc., etc. ...
}

并尝试以各种方式分配给它:

Php::Class<Mammal> clss( "Mammal" );

// some examples of what I've tried:
map[ "Animal::Mammal" ] = clss;
map[ "Animal::Mammal" ] = *clss;
map[ "Animal::Mammal" ] = &clss;
map[ "Animal::Mammal" ] = std::make_shared<Php::Class>( clss );
map[ "Animal::Mammal" ] = std::make_shared<Php::ClassBase>( clss );

map.insert( std::pair<std::string, Php::Class>( "Animal::Mammal", clss ) );
// etc., etc., etc. ...

但没有编译。

我遇到的编译错误范围从“operator* 未定义”到“不完整的类”(或类似的东西)到“模板参数无效”。

如您所见,我显然对这里需要做什么缺乏真正的了解。

我如何确定 map 的正确值类型应该是什么,然后如何正确地向 map 添加“类”(它甚至是正确的类?)吗?


PS:我非常有信心我已将所有必要的 header /文件正确地包含在适当的文件中。为了简洁起见,我在示例中省略了这些。

最佳答案

看起来像Php::Class是一个模板,所以你不能将它作为 mapped_typestd::map ,它不是一种类型。

对于每个要注册的类,您都必须有一个“注册我”功能,它会进入一个集合。

void registerMammal(Php::Namespace & ns) override 
{
Php::Class<Animal::Mammal> cls("Mammal");

cls.method<&Animal::Mammal::method>("method");
// ...

ns.add(std::move(cls));
}

std::vector<std::function<void(Php::Extension &, Php::Namespace &)>> AnimalRegistrations{ registerMammal, ... };

PHPCPP_EXPORT void *get_module() {
static Php::Extension extension( "animals", "0.1" );

Php::Namespace ns( "Animal" );

for (auto & reg : AnimalRegistrations)
{
reg(ns);
}

extension.add( std::move( ns ) );

return extension;
}

如果您有大量的命名空间需要注册,您最终可能会得到 std::map<std::string, std::vector<std::function<void(Php::Namespace &)>>>。 ,将名称与该 namespace 的注册函数集合相匹配。

你会像这样使用它

Php::Extension extension( "dabbler", "0.1" );

for (auto & pair : NamespaceMap)
{
Php::Namespace ns(pair.first);
for (auto & reg : pair.second)
{
reg(ns);
}
extension.add( std::move( ns ) );
}

关于c++ - 很难确定 std::map 的正确值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51749381/

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