Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

variadic templates - rozwijanie argumentów, błąd kompilacji

22 views
Skip to first unread message

Maciek

unread,
Sep 14, 2022, 12:34:23 PM9/14/22
to
kod poniższy działa:

void print() {
std::cout << "IN FUNCTION " << __func__ << std::endl;
std::cout << "ENDING ..." << std::endl;
return;
}

template<typename T, typename ... A>
auto print(T a, A... args) -> void {
std::cout << "IN FUNCTION " << __func__ << std::endl;
std::cout << a << std::endl;
print(args ...);
}

Natomiast w przypadku szablonu:

template<typename T, typename ... Types>
class T_Operators_tests {
public:
T_Operators_tests() {}
~T_Operators_tests() {}

void print() {
std::cout << "IN FUNCTION " << __func__ << std::endl;
std::cout << "ENDING ..." << std::endl;
return;
}
void print(T var1, Types... var2)
{
std::cout << var1 << std::endl;

this->print(var2...);
}
};

kompilator nie chce rozwinąć funkcji i nie pasuje mu liczba argumentów

Severity Code Description Project File Line Suppression State
Error C2661 'T_Operators_tests<int,int,int,int>::print': no overloaded function takes 3 arguments TestCpp1 operators_learn.hpp 37

Na czym polega mój błąd ?

Maciek Godek

unread,
Sep 16, 2022, 7:09:30 PM9/16/22
to
Cóż, nie za bardzo rozumiem C++, ale jeśli bym miał zgadywać,
to wygląda mi na to, że problem jest taki, że w tym drugim przypadku
każde ukonkretnienie szablonu powoduje powstanie nowej klasy,
w której metoda print przyjmuje konkretną liczbę argumentów.

Natomiast w ciele metody "print" próbujesz użyć (poprzez this)
metodę print, która będzie raczej przynależeć do innej klasy
(tzn. ukonkretnionej dla mniejszej liczby argumentów).

Wojciech Muła

unread,
Sep 17, 2022, 4:43:44 PM9/17/22
to
On Wednesday, September 14, 2022 at 6:34:23 PM UTC+2, Maciek wrote:
> kompilator nie chce rozwinąć funkcji i nie pasuje mu liczba argumentów

Nie może rozwinąć funkcji, bo ona jest w jednym wariancie. Parametryzację
masz na poziomie klasy, nie metody.

> Na czym polega mój błąd ?

Tak pi*drzwi sygnatura tej jednej metody to (int, int, int , int),
bo T = int, Types = {int, int, int}.

Więc to co się teraz dzieje w Twoim kodzie:

T_Operators_tests<int,int,int,int>::print(int val, {int, int, int} args)
{
std::cout << val;
print(args[0], args[1], args[2]);
}

Nie masz *w klasie* metody print(int, int, int) i to właśnie napisał Ci kompilator:
"no overloaded function takes 3 arguments".

Rozwiązanie to niezależnie od klasy sparametryzować metodę `print`:

template <typename U, typename... TU>
void print(U val, TU... args) {
// ...
}

BTW, doczytaj o perfect forwarding, bo przekazywanie
wartości w C++ to proszenie się o kłopoty.

w.

Przemek Biernat

unread,
Mar 29, 2023, 10:41:42 AM3/29/23
to
On Wednesday, September 14, 2022 at 6:34:23 PM UTC+2, Maciek wrote:
Przestańcie używać variatic templetes, bo to już jest zboczenie.
0 new messages