Передача параметра типа шаблона в качестве типа шаблона нетипичного параметра - PullRequest
0 голосов
/ 22 ноября 2018

Просто любопытно: с C ++ 17 и более поздними версиями мы можем использовать auto заполнитель для нетипичных параметров шаблона:

template<typename A, auto B>
class C {
public:
    A foo() { return B; }
};

Но можем ли мы вместо auto передать параметр типа шаблонаA?

example.cpp

template<typename A, A B>
class C {
public:
    A foo() { return B; }
};

int main()
{
    C<int, 5> c;
    std::cout << c.foo() << std::endl;

    return 0;
}

На практике мы можем, и лязг с -std = c ++ 11 позволяет это сделать.

$ g++ -std=c++11 example.cpp
$ ./a.out
5

А как же Стандарт?Я не нашел явного правила для этого.Спасибо!

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Но можем ли мы передать вместо "auto" параметр типа шаблона, определенный слева?

Конечно.Это старый способ.

Но способ auto позволяет избежать передачи типа A.

В C ++ 17 вы можете написать

template <auto B>
class C {
public:
    auto foo() { return B; }
};

поэтому нет необходимости передавать тип A.

Я не знаю, как сделать то же самое в C ++ 11 / C ++ 14.

Я имею в виду: если вы хотите, в C ++ 11 / C ++ 14 передать значение в шаблон ... если тип является фиксированным, нет проблем

template <int I>

, но сам тип может отличатьсяв C ++ 11 / C ++ 14 вы должны сначала передать тип, а затем значение, как в вашем примере .cpp

template <typename T, T A>

По-старому проблема заключается в том, что если вы хотитечтобы вызвать этот тип шаблона, вы должны быть избыточны и написать что-то как

C<decltype(x), x>  some_C_variable;

, и единственный известный мне способ избежать этой избыточности - это пройти через функцию make (что-то вроде make_tuple()) илиМакрос в стиле C.

В C ++ 17 вы можете просто написать

C<x>   some_C_variable

, а внутри класса / структуры шаблона C тип x можно получить из decltype(B).

Для стандартных ссылок C ++ 17 ...

Прежде всего, auto определяется как "placeolder"

От 10.1.7.4 (auto спецификатор), точка 1

Спецификаторы типа auto и decltype(auto) используются для обозначения типа заполнителя, который позднее будет заменен вычетом из инициализатора..

Это также верно для C ++ 11 / C ++ 14

Но стандартное добавление C ++ 17 для "Параметры шаблона" (17.1) в пункте 4Перечень, новый пункт 4.6

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

[...]

(4.6) тип, который содержит тип заполнителя (10.1.7.4)

0 голосов
/ 22 ноября 2018

Параметры шаблона можно разделить на:

1. Type parameters
2. Non type parameters
3. Template template parameters

В вашем случае оператор A B - это не шаблонный тип параметра, тип которого является параметром типа шаблона A.

Имейте в виду, что в вашем примере вы делаете:

return B;

вышеприведенное утверждение не выполнится для типов A, которые не copy constructible (это легко выразить понятием).

Имейте в виду (и, как было указано в комментариях), C ++ 17 обязывает копировать исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...