Шаблон Variadic с явными аргументами и размером ... Visual Studio 2013 - PullRequest
3 голосов
/ 01 мая 2019

Я пытался перечислить переменный кортеж, чтобы я мог выполнять определенные операции над каждым из его элементов.

#include <iostream>
#include <tuple>
#include <utility>

template <size_t N, typename ...Args>
typename std::enable_if<N == sizeof...(Args), void>::type
print(std::tuple<Args...> const& tuples)
{ }

template <size_t N, typename ...Args>
typename std::enable_if<(N < sizeof...(Args)), void>::type
print(std::tuple<Args...> const& tuples)
{
    std::cout << std::get<N>(tuples);
    print<N + 1>(tuples);
}

template <typename ...Args>
void printTuples(std::tuple<Args...> const& tuples)
{
    print<0>(tuples);
}

int main(int argc, char** argv)
{
    printTuples(std::make_tuple(1, 2.,3.));
    return 0;
}

В visual studio 2013 это приводит к следующей ошибке:

1>main.cpp(15): error C2770: invalid explicit template argument(s) for 'std::enable_if<N<1,void>::type print(std::tuple<_Types1...> &)'
1>main.cpp(15): error C2893: Failed to specialize function template 'std::enable_if<N==1,void>::type print(std::tuple<_Types1...> &)'

Это прекрасно компилируется в VS2015. Может ли кто-нибудь объяснить мне, почему sizeof ... (Args) был выведен в 1, даже если был передан кортеж с 3 аргументами? Кроме того, почему это ошибка в VS2013, а не в VS2015?

Примечание: я создал обходной путь (для VS2013), перечислив кортеж назад (начиная с конца)

1 Ответ

1 голос
/ 01 мая 2019

Может ли кто-нибудь объяснить мне, почему sizeof ... (Args) был выведен в 1, даже если был передан кортеж с 3 аргументами?

Я не могу.

Может быть, ошибка компилятора?

Или неадекватная поддержка C ++ 11?

Кроме того, почему это ошибка в VS2013, а не в VS2015?

Я не понимаю, как VS2015 может скомпилировать ваш код, потому что есть ошибка: ваши print() и printTuple() функции получают неконстантное l-значение, но вы вызываете printTuple() в main()

printTuples(std::make_tuple(1, 2.,3.));

с r-значением (которое несовместимо с неконстантной ссылкой на l-значение).

Предложение: измените ваши функции, чтобы получить const l-value reference

template <std::size_t N, typename ...Args>
typename std::enable_if<N == sizeof...(Args)>::type
   print (std::tuple<Args...> const & tuples)
 { } // ......................^^^^^

template <std::size_t N, typename ...Args>
typename std::enable_if<(N < sizeof...(Args))>::type
   print (std::tuple<Args...> const & tuples)
 { // ........................^^^^^
   std::cout << std::get<N>(tuples);
   print<N + 1u>(tuples);
 }

template <typename ...Args>
void printTuples (std::tuple<Args...> const & tuples)
 { print<0u>(tuples); } // ...........^^^^^
...