gpt4 book ai didi

c++ - 自动用指向部分特化函数成员的指针填充 vector

转载 作者:搜寻专家 更新时间:2023-10-31 02:22:58 25 4
gpt4 key购买 nike

我正在研究类似管道的设计模式。我的设计目标之一是通过提供指向某个数据类的函数成员的指针来启用管道段的动态链接。

每个数据类都有一组函数成员(代表数据类输出端口)使用整数模板参数进行索引。这些函数使用关键字 auto 动态推断返回类型, 但都接受相同的整数参数 c_Idx ,即 template <int N> auto getOutput(int c_Idx) const .与每个函数关联的功能 getOutput在一组部分专用结构中(由用户)定义getOutputImpl .因此,每个数据类可以有从 1 到某个固定数量的 K。输出数据端口。

为了允许以通用方式在管道段之间进行动态链接,它们可以存储在类型为 std::vector<boost::any> 的容器中。 .但是,我需要能够使用指向函数成员模板的指针自动填充此 vector 。

手动实现的示例如下所示

template<class TLeafType>
class AlgorithmOutput
{

protected:

std::vector<boost::any> OutputPorts;

public:

AlgorithmOutput()
{

//////////////////////////////////////////
// This procedure needs to be automated //
//////////////////////////////////////////
std::function<std::unique_ptr<double>(int)> pOutFun1 = std::bind(
std::mem_fn(
true ? &AlgorithmOutput<TLeafType>::getOutput<0> : nullptr
),
this,
std::placeholders::_1
);
OutputPorts.push_back(pOutFun1);

std::function<std::unique_ptr<int>(int)> pOutFun2 = std::bind(
std::mem_fn(
true ? &AlgorithmOutput<TLeafType>::getOutput<1> : nullptr
),
this,
std::placeholders::_1
);
OutputPorts.push_back(pOutFun2);

}

virtual ~AlgorithmOutput() {}

protected:

TLeafType* asLeaf(void)
{
return static_cast<TLeafType*>(this);
}

TLeafType const* asLeaf(void) const
{
return static_cast<TLeafType const*>(this);
}

public:

template <int N>
auto getOutput(int c_Idx) const
{
return asLeaf() -> getOutput<N>(c_Idx);
}

boost::any getOutputPort(int PortIdx)
{
return OutputPorts[PortIdx];
}

};

class PipeOutputClass: public AlgorithmOutput<PipeOutputClass>
{

public:

template <int N>
auto getOutput(int c_Idx) const
{
return getOutputImpl<N>::apply(this, c_Idx);
}

template<int N, typename S> friend struct getOutputImpl;

template<int N, typename = void>
struct getOutputImpl
{
static auto apply(
PipeOutputClass const* p_Self,
int c_Idx
)
{ throw std::runtime_error("Wrong template argument."); }
};

template <typename S>
struct getOutputImpl<0, S>
{
static std::unique_ptr<double> apply(
PipeOutputClass const* p_Self,
int c_Idx
)
{
std::unique_ptr<double> mydouble(new double(10));
return mydouble;
}
};

template <typename S>
struct getOutputImpl<1, S>
{
static std::unique_ptr<int > apply(
PipeOutputClass const* p_Self,
int c_Idx
)
{
std::unique_ptr<int > myint(new int(3));
return myint;
}
};

};

上面例子的问题是我定义了成员函数指针pOutFunX手动,而我想自动执行此过程。

请注意,我并未考虑与上述指定设计有显着差异的设计解决方案。


在这里,我提出了一些关于解决此问题的可能方法的想法。我为我目前正在考虑的解决方案制定了一个计划,如果您尝试回答这个问题,它可能会有用:

  1. 获取名为getOutputImpl 的用户定义的部分专用结构的数量.
  2. 对于每个这样的结构,确定其名为 apply 的成员的输出类型.
  3. 设置一个(递归)元模板过程,创建指向具有相关签名的函数的指针,并将它们添加到 OutputPort vector 。

我假设上面的步骤 1-3 都必须在编译时完成。我不关心解决方案的美学,如果它不需要用户设计数据输出类的任何干预。但是,我不想使用自定义编译器宏。

这篇文章展示了如何 infer a member function signature ,这可能会有用。

最佳答案

我们知道,对于每个未定义 getOutput 的模板参数,其返回类型都是 void。所以我们可以按如下方式确定K:

template <int K>
constexpr std::enable_if_t<std::is_void<decltype(getOutput<K>(0))>{}, int> getK() {
return K-1;
}
template <int K>
constexpr std::enable_if_t<!std::is_void<decltype(getOutput<K>(0))>{}, int> getK() {
return getK<K+1>();
}

此外,您还可以“自动化”您的 push_back,如下所示:

     AlgorithmOutput() : AlgorithmOutput(std::make_index_sequence<getK<0>()>()) {}

private:


template <std::size_t... indices>
AlgorithmOutput( std::integer_sequence<indices...> )
{
(void)std::initializer_list<int> {
(OutputPorts.push_back([this] (int i) {return getOutput<indices>(i);}, 0)...
};
}

(所有代码未经测试,仅是草图!)

关于c++ - 自动用指向部分特化函数成员的指针填充 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29733250/

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