gpt4 book ai didi

c++ - 以内部模板化 typedef 作为参数的模板化延迟初始化单例

转载 作者:行者123 更新时间:2023-11-28 05:47:03 24 4
gpt4 key购买 nike

我有大量我无法控制的不同枚举类型。例如(数百个枚举中的一个):

enum ColorType {
RED,
GREEN,
BLUE };

我希望允许 C++ 客户端将他们希望的任何 std::string 绑定(bind)到枚举类型的各个值(但以双向方式是唯一的)。我使用 boost bimap (v1.60) 让它工作 - 在这里忽略边界检查等:

template <typename L, typename R> boost::bimap<L, R>
makeBimap(std::initializer_list<typename boost::bimap<L, R>::value_type> list)
{
return boost::bimap<L, R>(list.begin(), list.end());
};

template<typename E> class EnumWithString
{
private:
typedef typename boost::bimap<E, std::string > BMEnumType;
const BMEnumType _biMap;

EnumWithString(const EnumWithString<E>&) = delete;
EnumWithString& operator=(const EnumWithString<E>&) = delete;
public:
EnumWithString(const BMEnumType& biMap) : _biMap(biMap) {};
const std::string& getString(const E& e) const {
return this->_biMap.left.at(e);
}
const E& getEnum(const std::string& s) const {
return this->_biMap.right.at(s);
}
};

例如生成客户端代码(为了可读性,请随意想象 typedef):

EnumWithString<ColorType> stringBoundEnum(makeBimap<ColorType, std::string>({ { ColorType::RED, "Rouge" },  
{ ColorType::BLUE, "Bleu" },
{ ColorType::GREEN, "Vert" } }));
cout << stringBoundEnum.getString(ColorType::GREEN) << endl;
cout << stringBoundEnum.getEnum("Bleu") << endl;

这给出了正确的输出。棘手的一点是我需要这些创建的映射(例如 stringBoundEnum)是单例,即我正在寻找一个类似(再次想象 typedefs)的接口(interface):

EnumWithStringSingleton<ColorType>::setInstance(makeBimap<ColorType, std::string>({ { ColorType::RED, "Rouge" },
{ ColorType::BLUE, "Bleu" },
{ ColorType::GREEN, "Vert" } })); // called only once by client

cout << EnumWithStringSingleton<ColorType>::getInstance().getString(ColorType::GREEN) << endl;

理想情况下,我正在寻找可以与采用单个 CTOR 参数的模板化单例一起使用的东西,例如:

template <typename T, typename CTORArgument> class LazyInitSingleton
{
public:
static T& getInstance(const CTORArgument& arg)
{
static T& theInstance(arg);
return theInstance;
}
private:
};

问题是,对于我的情况,CTORArgument 是在模板类中定义的模板化 typedef。我很想知道人们是如何解决这个问题的(也许是 SFINAE?)。

最佳答案

简单的解决方案是使您的单例更符合 EnumWithString 的需要:

template <typename EnumWithStringType> class LazyInitSingleton
{
public:
// You have to make BMEnumType public
static EnumWithStringType& getInstance(const typename EnumWithStringType::BMEnumType& arg)
{
static EnumWithStringType theInstance(arg);
return theInstance;
}
};

LazyInitSingleton<EnumWithStringType<ColorType>>::getInstance(...);

甚至

template <typename EnumType> class LazyInitSingleton
{
public:
static EnumWithString<EnumType>& getInstance(const EnumWithString<EnumType>::BMEnumType& arg)
{
static EnumWithString<EnumType> theInstance(arg);
return theInstance;
}
};

LazyInitSingleton<ColorType>::getInstance(...);

关于c++ - 以内部模板化 typedef 作为参数的模板化延迟初始化单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36024258/

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