Использование шаблона, когда ни один из типов не имеет общего кода

У меня есть следующий класс:

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 классу Container, который не знает CContainer. Действительно, в будущем я надеюсь, что CContainer (который я получил через C API) исчезнет и что значения вместо этого упорядочены в std :: vector или std :: list. Из-за этого не нужно менять интерфейс моего контейнера, и его не должно волновать, как данные хранятся в памяти.

Имея это в виду, я бы предпочел вместо этого что-то примерно в этом направлении:

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

Решение

Просто сделай очевидное. Не требуется, чтобы специализация шаблона имела что-то общее с другой специализацией или с оригинальным шаблоном. Так:

class IIntValueSetter {
};

template <class Ty> class ValueSetter; // declared but not defined

template <>
class ValueSetter<int> : public IIntValueSetter {
// whatever
};

ValueSetter<int> vsi;
4

Другие решения

Если я вас правильно понял, вам просто нужно написать шаблон класса:

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.
};
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;
};
0