WedX - журнал о программировании и компьютерных науках

Простая проверка концепции

Скажем, у меня есть простой шаблон, подобный этому:

template<typename T>
class A {};

И я хочу указать, что параметр типа T относится к какому-то несвязанному типу X<U>, где U неизвестен (или не может быть указан).

Есть ли способ выразить это как концепцию?

06.03.2017

Ответы:


1

Есть ли способ выразить это как концепцию?

Вам не нужна концепция, специализация шаблона класса отлично работает в вашем случае.
Например, вы можете сделать это:

template<typename T>
class A;

template<typename U>
class A<X<U>> { /* ... */ };

Таким образом, если A не создается с типом формы X<U> (где U неизвестно), вы получите ошибку времени компиляции, поскольку первичный шаблон не определен. Другими словами, это не будет работать для всех типов, кроме X<U> (для каждого U), где последний соответствует специализации шаблона класса, которая имеет правильное определение.

Обратите внимание, что я предположил, что X является известным типом. Это неясно из вашего вопроса.
В любом случае, если это не так, и вы хотите принимать типы формы X<U> для каждого X и каждого U, вы все равно можете сделать это:

template<typename T>
class A;

template<template<typename> class X, typename U>
class A<X<U>> { /* ... */ };

В качестве минимального рабочего примера:

template<typename>
struct S {};

template<typename>
class A;

template<typename U>
class A<S<U>> {};

int main() {
    A<S<int>> aSInt;
    A<S<double>> aSDouble;
    // A<char> aChar;
}

И A<S<int>>, и A<S<double>> в порядке, и пример компилируется. Если вы переключите комментарий, он больше не будет компилироваться, поскольку A<char> вообще не определен.


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

#include<type_traits>

template<typename>
struct X {};

template<typename>
struct is_xu: std::false_type {};

template<typename U>
struct is_xu<X<U>>: std::true_type {};

template<typename T>
struct A {
    static_assert(is_xu<T>::value, "!");
    // ...
};

int main() {
    A<X<int>> aXInt;
    A<X<double>> aXDouble;
    // A<char> aChar;
}

То есть, учитывая универсальный тип T, статические утверждения его фактического типа с помощью другой структуры (is_xu в примере), которая проверяет, имеет ли T форму X<U> (для каждого U) или нет.


Мои два цента: специализация шаблона класса легче читать и понимать с первого взгляда.

06.03.2017
  • Это на самом деле не отвечает на вопрос 06.03.2017
  • @Кубби Хорошо. Так что я не могу на самом деле улучшить его. 06.03.2017

  • 2
    template <typename T, template <typename> class C>
    concept bool Template = requires (T t) { {t} -> C<auto>; };
    

    Теперь задан шаблон класса:

    template <typename T>
    struct X {};
    

    параметр шаблона типа может быть ограничен с помощью:

    template <typename T> requires Template<T, X>
    class A {};
    

    or:

    template <Template<X> T>
    class A {};
    

    ДЕМО

    Это будет работать и для типов, производных от X<U>.

    06.03.2017
  • Я бы сказал, что для этого требуется C++2x или более поздняя версия (к сожалению). При этом есть ли хороший ресурс, чтобы углубиться в концепции, которые вы можете предложить? Спасибо. 06.03.2017
  • Просто нужен компилятор, поддерживающий концепцию TS. Вскоре он будет реализован во внешнем интерфейсе Clang, поэтому он также будет реализован в Visual Studio. @PiotrSkotnicki, если бы вы инвертировали аргумент шаблона концепции, вы могли бы объявить template<Template<X> T> class A{} 06.03.2017
  • @Oliv Вы правы, но я подозреваю, что ОП хочет решение, которое работает сегодня, а не в ближайшее время. ;-) ... Во всяком случае, мне нравится этот ответ, не поймите меня неправильно. 06.03.2017
  • @ Олив, спасибо, я не мог придумать этот синтаксис самостоятельно, хотя знал, что это должно быть возможно. 06.03.2017
  • @skypjack Concepts TS — единственный известный мне ресурс 06.03.2017
  • @PiotrSkotnicki На самом деле это имеет смысл. ;-) 06.03.2017
  • @skypjack Если вас интересует концепция, вот список источников, которые я использовал, чтобы научиться ее использовать: [en.cppreference.com/w/cpp/language/constraints ], руководство Stroustrup [stroustrup.com/good_concepts.pdf] и нормативные документы (прочитав их, я избавился от некоторых заблуждений!) [open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4630.pdf] 06.03.2017
  • Является ли синтаксис C<auto> правильным после того, как wg21.link/p0127r2 был проголосован за C++17? 06.03.2017
  • @dyp gcc реализовал этот автоматический вывод типа в параметре шаблона, и он на удивление работает... Кажется, что auto - это особая концепция, которая может принимать либо тип, либо значение в зависимости от контекста... 06.03.2017
  • Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]