Отключить специализацию класса, используя понятия

public void ExpoetToCSV(DataTable dtDataTable, string strFilePath)
{

    StreamWriter sw = new StreamWriter(strFilePath, false);
    //headers   
    for (int i = 0; i < dtDataTable.Columns.Count; i++)
    {
        sw.Write(dtDataTable.Columns[i].ToString().Trim());
        if (i < dtDataTable.Columns.Count - 1)
        {
            sw.Write(",");
        }
    }
    sw.Write(sw.NewLine);
    foreach (DataRow dr in dtDataTable.Rows)
    {
        for (int i = 0; i < dtDataTable.Columns.Count; i++)
        {
            if (!Convert.IsDBNull(dr[i]))
            {
                string value = dr[i].ToString().Trim();
                if (value.Contains(','))
                {
                    value = String.Format("\"{0}\"", value);
                    sw.Write(value);
                }
                else
                {
                    sw.Write(dr[i].ToString().Trim());
                }
            }
            if (i < dtDataTable.Columns.Count - 1)
            {
                sw.Write(",");
            }
        }
        sw.Write(sw.NewLine);
    }
    sw.Close();
}
8
задан Lyberta 16 January 2019 в 17:10
поделиться

3 ответа

Вы не используете понятия. В концептуальном мире конструктор span будет выглядеть так с синтаксисом concept-ts:

struct span{
   span(const ContiguousRange&);
   span(ContiguousRange&);
   span(const span&) =default;
   span(span&) =default;
   };

или с c ++ 20:

struct span{
   span(const ContiguousRange auto&);
   span(ContiguousRange auto&);
   span(const span&) =default;
   span(span&) =default;
   };

Понятия здесь для облегчения абстракции. Так что если ваш интерфейс становится более сложным при использовании концепций, то вы пропустили абстракцию. Абстракция здесь ContiguousRange (спасибо @Lyberta).

0
ответ дан Oliv 16 January 2019 в 17:10
поделиться

Вы можете использовать черты типа, чтобы проверить, является ли некоторый тип специализацией span или std::array. Это работает для меня:

#include <type_traits>

template<typename, std::ptrdiff_t> class span;

template <typename T>
struct is_array : std::false_type { };
template <typename T, size_t N>
struct is_array<std::array<T, N>> : std::true_type { };

template <typename T>
struct is_span : std::false_type { };
template <typename T, std::ptrdiff_t P>
struct is_span<span<T, P>> : std::true_type { };

template <typename T>
concept bool NotSpanNotArray = !is_array<T>::value && !is_span<T>::value;

template<typename, std::ptrdiff_t> class span {
public:
  template<NotSpanNotArray T> constexpr span(T& cont);
  // template<NotSpanNotArray T> constexpr span(const T& cont);
};

Рабочая демонстрация: https://wandbox.org/permlink/M0n60U8Hl4mpacuI

Просто я не уверен на 100%, является ли такой Решение соответствует тому, что участвуют в разрешении перегрузки тогда и только тогда, когда требуется. Некоторые юристы могут прояснить это.


ОБНОВЛЕНИЕ

Я только что понял, что std::is_array работает только для «обычных» массивов, а не std::array. Поэтому я добавил также особенность типа is_array.

0
ответ дан Daniel Langr 16 January 2019 в 17:10
поделиться

Сначала создайте черту для проверки специализаций. array и span выглядят одинаково в том смысле, что они принимают параметр типа и параметр нетипичного типа:

template <typename T, template <typename, auto> class Z>
struct is_specialization : std::false_type { };
template <typename A, auto V, template <typename, auto> class Z>
struct is_specialization<Z<A,V>, Z> : std::true_type { };

template <typename T, template <typename, auto> class Z>
inline constexpr bool is_specialization_v = is_specialization<T, Z>::value;

И затем мы можем построить концепцию из этого:

[ 111]

Который вы бы использовали следующим образом:

template <typename Element, std::ptrdiff_t Extent = -1>
struct span {
    template <typename C> requires AllowedContainer<C, Element>
    span(C&);
    template <typename C> requires AllowedContainer<C const, Element>
    span(C const&);
};

Требование к const -мости не позволяет использовать хороший синтаксис частичного-концепта-идентификатора , но мы могли бы просто добавьте еще одну концепцию для этого:

template <typename T, typename E>
concept ConstAllowedContainer = AllowedContainer<T const, E>;

template <typename Element, std::ptrdiff_t Extent = -1>
struct span {
    template <AllowedContainer<E> C>      span(C&);
    template <ConstAllowedContainer<E> C> span(C const&);
};

Не уверен, что здесь есть более умный подход.


Но на самом деле вся эта пара конструкторов, вероятно, является ошибкой, и вы хотите сделать ссылку на пересылку:

template <typename Element, std::ptrdiff_t Extent = -1>
struct span {
    template <AllowedContainer<E> C>
    span(C&&);
};

Этот последний подход требует нескольких настроек для концепция (все remove_cv_t должны стать remove_cvref_t).

0
ответ дан Barry 16 January 2019 в 17:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: