gpt4 book ai didi

c++ - 使用不同/未知类型的类模板初始化 vector

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:44:44 25 4
gpt4 key购买 nike

为自己开发一个命令行解析器。我立刻知道我会在这个构造上遇到麻烦,并希望有人可以提供解决方法的建议。

我想将参数的参数列表(基于模板)存储在 vector 中可能包含各种不同的数据类型。但据我了解,您必须定义 vector<template<type>>静态地。有没有办法排除多种类型?

这是我的意思的一个例子:

#include <vector>
#include <memory>

namespace clparser
{
class CommandLine {
private:
std::vector<Parameter<AnyType??>*> ArgumentList;

public:

void Add(Parameter<AnyType??>* Parameter) { ArgumentList.push_back(Parameter); }
};


template<typename T>
class Parameter {
private:
const char *ShortOption;
const char *LongOption;
const char *Description;
const bool RequiredField;
const char *DefaultValue;


public:
Parameter(const char *ShortOption, const char *LongOption, const char *Description, const bool RequiredField, const char *DefaultValue)
: ShortOption(ShortOption), LongOption(LongOption), Description(Description), RequiredField(RequiredField), DefaultValue(DefaultValue)
{

}
};
}

最佳答案

如果您可以接受 C++11 解决方案,我建议您使用我的命令行解析器的 iper 简化版本。希望对您有所启发。

我的解决方案背后的想法是使用基础/派生多态性:纯虚拟 class optBase这是一组专用于选项的模板类的基础(在以下示例中,只有 class opt ;但在我的解析器中还有其他三个)。

然后(不是模板)class yData包含 std::unique_ptr<optBase> (如果你使用一个指向 optBase 的简单指针,你也可以在 C++98 中编译,我想;但我建议使用 C++11 或更新版本)。

class yData (大致)对应于您的 class Parameter但是(这里是诀窍)不是模板类;包含指向模板类的基指针。

我的 class yarg对应你的class clparser和我的 std::map<int, yData> idMap (大致)对应于您的 std::vector<Parameter<AnyType??>*> ArgumentList .

喂食idMap ,我开发了一套模板方法(每个派生自 optbase 类);在以下示例中,您可以看到其中一个的 iper 简化版本:addOpt() (大致对应于您的 Add() )。

在下面的例子中你可以看到一点 main()有几个用途 addOpt() : 第一个为 int参数和第二个 double参数(重要(也是我的解决方案的弱点):返回值必须保存在引用变量中,而不是简单变量中)。

#include <map>
#include <memory>


class optBase
{
public:
// some pure virtual methods
};

template <typename X>
class opt : public optBase
{
private:
X val { };
// ...

public:

opt ()
{ }

opt (X const & v0)
: val { v0 } // ...
{ }

X const & getVal () const
{ return val; }

X & getVal ()
{ return val; }

// ...
};

// other optBase derived classes (for flags, containers of values, etc)

class yData
{
private:
// ...
std::unique_ptr<optBase> optB;

public:
yData (/* other arguments */ std::unique_ptr<optBase> optB0)
: /* something else */ optB { std::move(optB0) }
{ }
// ...
std::unique_ptr<optBase> const & getPnt () const
{ return optB; }
};

class yarg
{
private:
// ...
std::map<int, yData> idMap;
// ...

public:
// ...
template <typename T>
T & addOpt (/* other arguments */ T const & def = T())
{
int id { /* some value */ };
opt<T> * optP { nullptr };
// ...&
idMap.emplace(std::piecewise_construct,
std::forward_as_tuple(id),
std::forward_as_tuple(/* other arguments */
std::unique_ptr<optBase>(optP = new opt<T>(def))));

return optP->getVal();
}

};

int main ()
{
yarg y;

// important: use a *reference*
auto & pi = y.addOpt(3); // pi is a int
auto & pd = y.addOpt(3.0); // pd is a double

static_assert(std::is_same<decltype(pi), int &>::value, "!");
static_assert(std::is_same<decltype(pd), double &>::value, "!!");
}

关于c++ - 使用不同/未知类型的类模板初始化 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41245958/

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