У меня есть класс контейнера, который имеет std::vector<T>
элемент, который я инициализировать с конструктором, который принимает size_t n_items
. Я хотел бы инициализировать этот вектор с моей собственной функцией Zero(), которая по умолчанию returns 0;
, но если существует статический член T::Zero
, я хочу вернуть это вместо этого.
В моей первой попытке я использую выражение SFINAE, но это не удалось из-за неоднозначной перегрузки, поскольку и общая версия Zero и Zero имеет одну и ту же подпись без аргументов. Итак, теперь я пытаюсь преобразовать код в классы с operator()
.
Как мне кажется, мне нужно использовать std::enable_if
, но я не уверен, как это сделать.
неудачная попытка
#include <cassert>
#include <iostream>
#include <vector>
template<typename T>
struct Zero
{
T operator() const { return 0; }
};
template<typename T>
struct Zero
{
auto operator() const ->
decltype(T::Zero)
{
return T::Zero;
}
};
struct Foo
{
char m_c;
static Foo Zero;
Foo() : m_c('a') { }
Foo(char c) : m_c(c) { }
bool operator==(Foo const& rhs) const { return m_c==rhs.m_c; }
friend std::ostream& operator<<(std::ostream& os, Foo const& rhs)
{
os << (char)(rhs.m_c);
return os;
}
};
Foo Foo::Zero('z');
int
main(int argc, char** argv)
{
std::vector<unsigned> v(5, Zero<unsigned>());
std::vector<Foo> w(3, Zero<Foo>() );
for(auto& x : v)
std::cout << x << "\n";
std::cout << "---------------------------------\n";
for(auto& x : w)
{
assert(x==Foo::Zero);
std::cout << x << "\n";
}
std::cout << "ZERO = " << Foo::Zero << "\n";
return 0;
}
То, что 'zero' также может быть статической функцией-членом вместо статического элемента данных. – dyp
Также возможно использовать пользовательский распределитель для 'std :: vector', инициализация которого использует настраиваемый' zero'. – dyp