我有以下课程:
class ValueSetter: public IValueSetter
{
public:
explicit ValueSetter(CContainer* container)
: _container(container)
{
}
virtual void operator()(const int value, const int index) const
{
_container->values[index].value.i = value;
}
virtual void operator()(const double value, const int index) const
{
_container->values[index].value.d = value;
}
virtual void operator()(const std::string& value, const int index) const
{
...
_container->values[index].value.s = _strdup(value.c_str());
}
private:
CContainer* _container;
};
这个类在CContainer上运行,它将数据存储在一个联合缓冲区中。我将ValueSetter传递给一个不知道CContainer的Container类。实际上,在未来我希望CContainer(我通过C API接收)将消失,而值则组织在std :: vector或std :: list中。 My Container的界面不应该因此而改变,也不应该关心数据如何存储在内存中。
考虑到这一点,我更倾向于大致沿着这些方向:
class IntValueSetter: public IIntValueSetter
{
public:
explicit IntValueSetter(Container* container)
: _container(container)
{
}
virtual void operator()(const int value, const int index) const
{
_container->values[index].value.i = value;
}
private:
CContainer_3* _container;
}
或:
class IntValueSetter: public IIntValueSetter
{
public:
explicit IntValueSetter(std::vector<int> values)
: _values(values)
{
}
...
}
但我需要能够按如下方式使用它们:
ValueSetter<int> valueSetter;
而不是
IntValueSetter valueSetter;
我该怎么做?
答案 0 :(得分:4)
做的很明显。不要求模板专业化与其他专业化或原始模板有任何共同之处。所以:
class IIntValueSetter {
};
template <class Ty> class ValueSetter; // declared but not defined
template <>
class ValueSetter<int> : public IIntValueSetter {
// whatever
};
ValueSetter<int> vsi;
答案 1 :(得分:0)
如果我说得对,你只需要编写一个类模板:
template <typename T>
class ValueSetter
{
public:
explicit ValueSetter(std::vector<T> values): _values(values)
{
}
virtual void operator()(const T value, const int index) const
{
_container->values[index].value.i = value;
}
// etc.
};
答案 2 :(得分:0)
我想我正在寻找这样的东西。我只在下面实现了int,但每种类型都会得到自己的接口类和实现类。我很想听听你对这种方法的评论!
template<typename V>
class IValueSetter
{
public:
};
template<>
class IValueSetter<std::string>
{
public:
virtual void operator()(const std::string& value, int index) const = 0;
};
template<typename V>
class ValueSetter
{
};
template<>
class ValueSetter<std::string>: public IValueSetter<std::string>
{
public:
explicit ValueSetter2(CContainer* container)
: _container(container)
{
}
void operator()(const std::string& value, int index) const
{
_container->values[index].value.s = _strdup(value.c_str());
}
private:
CContainer* _container;
};
template<>
class NewValueSetter<std::string>: public IValueSetter<std::string>
{
public:
explicit NewValueSetter(std::shared_ptr<std::list<std::string>> values)
: _values(values)
{
}
void operator()(const std::string& value, int index) const
{
(*values)[index] = value;
}
private:
std::shared_ptr<std::list<std::string>> _values;
};