Operator<< szablonowy, dedukcja.

0

Cześć :)

template<typename T>
std::ostream& operator<<(std::ostream& os,  const  typename K<T>::CountedNode& l){
    return os;
}


int main() {
     K<int>::CountedNode c;
    std::cout << c;

    return 0;
}

Powyższy kod powoduje błąd:

no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘K<int>::CountedNode’

Natomiast, jeżeli dodam definicję:

std::ostream& operator<<(std::ostream& os,  const  typename K<int>::CountedNode& l){
    return os;
}

Kod się kompiluje, no więc widać, że jest jakiś problem z dedukcją. Dlaczego?

1

czym jest CountedNode?

0

zagnieżdżoną strukturą klasy K

0

Trochę tutaj strzelam, ale z typu obiektu c (K<int>::CountedNode) nie da się jednoznacznie wydedukować, że szablonowy argument T to int. Nietrudno sobie wyobrazić sytuację, w której K<int>::CountedNode jest tym samym co powiedzmy K<double>::CountedNode.
Jeżeli powiesz explicite, że argument szablonu to int to wtedy nie ma problemu

operator<< <int>(cout, c);
1

Możesz zdefiniować operator<< jako funkcję zaprzyjaźnioną z CountedNode lub K (wewnątrz CountedNode lub K). Dzięki temu będzie widoczna przez ADL. Na szybko nie przychodzi mi lepsze rozwiązanie do głowy.

0

K<int>::CountedNode jest tym samym co powiedzmy K<double>::CountedNode.

Czy masz na myśli taką sytuację, w której struktura zagnieżdżona nie korzystałaby z parametru T?

0

Dzięki temu będzie widoczna przez ADL

Co masz na myśli i dlaczego nie jest widoczna tak jak ja próbuję?

3

Bo tak działa język. Ze względu na możliwe specjalizacje szablonów kompilator nie jest w stanie założyć, że typ U jest ściśle pochodny po K<T>, gdy U to K<T>::CountedNode.

1

Zdefiniuj operator<< w klasie/strukturze K jako friend i po problemie:

#include <iostream>
using namespace std;

template < typename T >
struct K
{
	struct CountedNode
	{
	};
	
	friend std::ostream& operator<<(std::ostream& os, const CountedNode& l){
    	return os;
	}
};



int main() {
    K<int>::CountedNode c;
    std::cout << c;
 
    return 0;
}
0

@mwl4, to już jasne, pytanie było inne.

4

Identyczny przykład: http://stackoverflow.com/questions/12566228/candidate-template-ignored-because-template-argument-could-not-be-inferred

n3337 14.8.2.5/4

In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

n3337 14.8.2.5/5

The non-deduced contexts are:

— The nested-name-specifier of a type that was specified using a qualified-id.

1 użytkowników online, w tym zalogowanych: 0, gości: 1