如何列出初始化没有 std::initializer_list 的模板化类,使其具有固定大小

how to list initialise a templated class without std::initializer_list so it has a fixed size

本文关键字:std 初始化 何列出 initializer list      更新时间:2023-10-16

不使用stdlib(由于arduino平台(,我正在尝试创建一个类似类的映射,我可以用来运行给定字符串的函数。它的大小需要在创建时固定。所以我一直在试图弄清楚如何使用模板或可变参数模板创建它,但我不够精通让它工作。

理想情况下,它将创建与此类似的内容

class parent_class {
StringMap mymap{
{ "command1", parent_class::member_function },
{ "command2", parent_class::member_function },
...
};
...
}

但是我一直在努力寻找模板和可变参数的正确组合,我最终确实得到了一些使用 std::initializer_list 的东西,但这在 Arduino 平台上不可用,所以它是一个非启动器。

我真的不在乎它在引擎盖下是如何工作的,我已经通过文档和示例找到了实现这一目标的方法,感觉它应该能够完成。

使用它,我将在地图上进行二分搜索,如果没有完全匹配,则最近的邻居将显示为建议。 但我被困在底层机制上。 下面是我在卡住并重写然后再次陷入困境之前最接近的。

#include <string>
template< typename T >
struct Pair {
std::string path;
T object;
};
template< class T >
struct StringMap {
StringMap( T args[] ){
}
};
class Parent {
void testfunc(int data){}
void testfunc2(int data){}
StringMap<void (Parent::*)(int)> map{
Pair<void (Parent::*)(int)>{"command1", &Parent::testfunc},
Pair<void (Parent::*)(int)>{"command2", &Parent::testfunc2}
};
};
int main(){
Parent test;
//Then i could run something like test.run("command1", 1);
return 0;
}```
Compiler commandline for the arduino studio starts like this:
avr-gcc/5.4.0-atmel3.6.1-arduino2/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega2560

一种方法是只依赖纯数组成员的聚合初始化:

template< class T, int N>
struct StringMap {
// Do not add a constructor!
Pair<T> values[N];
};
class Parent {
void testfunc(int data){}
void testfunc2(int data){}
StringMap<void (Parent::*)(int), 2> map{
Pair<void (Parent::*)(int)>{"command1", &Parent::testfunc},
Pair<void (Parent::*)(int)>{"command2", &Parent::testfunc2}
};
};

https://godbolt.org/z/sjbE4B

为了简单起见,我保留了手动指定的大小。可能有一种方法不仅可以推断大小,还可以推断T,但我认为代码不会以这种方式变得更清晰。

另请注意,如果指定太大的N,则其余数组条目将被初始化为零,您必须正确设置该数组条目。(但是,如果使用太多初始值设定项,则确实会出现编译时错误(。

所以我回过头来回顾了关于统一初始化的文档,并以此为起点,但我希望它尽可能简化。 在 godbolt.org 和Arduino工作室中编译。

#include <string>
template<typename T>
struct Pair {
std::string first;
T second;
};
template<class T,int size>
struct Map {
template<class... Ts> //somehow enableif size and parameter pack match
Map(Ts ...input){
for( int i = 0; i < sizeof...(input); ++i){
}
}
//Rudimentary linear search
T find(std::string name){
for( auto i : list){
if(! i.first.compare(name) ) return i.second;
}
}
Pair<T> list[size];
};
struct Parent{
void func1( int num ){}
void func2( int num ){}
void func3( int num ){}
Map<void (Parent::*)(int),3> map{
Pair<void (Parent::*)(int)>{"func1",&Parent::func1},
Pair<void (Parent::*)(int)>{"func2",&Parent::func2},
Pair<void (Parent::*)(int)>{"func3",&Parent::func3}
};
void call(std::string name){
auto func = map.find(name);
(this->*func)( 1 );
}
};
int main(){
Parent parent;
parent.call("func1");
return 0;
}

我想你尝试这样的事情:

template<class T, bool(*cmp)(int,int)>
class strMap{

};