Почему использование пакета параметров целочисленного значения запрещено после пакета параметров типа в C ++ 11? - PullRequest
8 голосов
/ 12 января 2012

Вопрос почти не имеет смысла без примера. Вот что я пытаюсь сделать.

В целом C ++ допускает следующее:

template<class T, class U, T t, U u>
void func() {}

func<char, int, 'A', 10>();

Но похоже, что его естественное расширение не работает.

template<class...T, T... t>
void func() {}

func<char, int, 'A', 10>(); 

И clang, и g ++ 4.7 отклоняют приведенный выше код. Ошибка отображается там, где выполняется создание экземпляра. Мне кажется, что два вариационных списка должны быть проанализированы однозначно, потому что первый имеет типы, а другой имеет только целые значения.

Если вышеупомянутое не предназначено для работы, я думаю, что следующее также не будет работать.

template <class Ret, class... Args, Ret (*func)(Args...)>
class Foo {};

Я думаю, что шаблон Foo довольно полезен.

Ответы [ 2 ]

8 голосов
/ 12 января 2012

( Дополнительно: Непосредственно отвечая на ваш первый вопрос, вы также можете превратить template<class...T, T... t> void func() {} в шаблон внутри шаблона. Это не работает в g ​​++ 4.6, но работает в clang 3.0, следовательно, мне понадобилось время, чтобы найти его.)

Поместите шаблон внутри шаблона:

template<class ... T>
struct func_types {
   template <T ... t>
   static void func_values() {
       // This next line is just a demonstration, and 
       // would need to be changed for other types:
       printf("%c %d\n", t...);
   }
};

int main() {
    func_types<char, int> :: func_values<'A', 10>();
}

Допустим ли шаблон внутри шаблона? Альтернативой является использование кортежей с func< tuple<char,int> , make_tuple('A',10) >. Я думаю, что это выполнимо, но вам, возможно, придется свернуть свой собственный класс кортежей (кажется, что make_tuple не является constexpr.

Наконец, вы можете реализовать шаблон Foo следующим образом:

template<typename Ret, typename ...Args>
struct Foo {
        template< Ret (*func)(Args...)>
        struct Bar {
                template<typename T...>
                Bar(T&&... args) {
                        cout << "executing the function gives: "
                           << func(std::forward(args)...) << endl;
                }
        };
};

int main () {
    Foo<size_t, const char*> ::  Bar<strlen> test1("hi");
    Foo<int, const char*, const char*> ::  Bar<strcmp> test2("compare","these");
}

Этот последний код находится на ideone . Чтобы продемонстрировать, я реализовал конструктор для пересылки аргументов в функцию, которая является кодом в шаблон.

2 голосов
/ 12 января 2012

Потому что никто не думал, что стоило бы иметь эту функцию. Дизайн шаблона variadic должен был быть простым и работающим. Другие потенциально расширенные и полезные функции, которые мы не включили, *. 1001 *

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