1

Я экспериментировал с вызовом функции шаблона друга без параметра, который определен в шаблоне класса. Я не нашел решения для этого случая и решил свою проблему по-другому, но во время моих экспериментов я неожиданно обнаружил интересный фрагмент кода. Это работает, но я не знаю, почему. Вот этот пример:Вызов функции шаблона друга без параметров, определенных в шаблоне класса

#include <iostream> 

template<class T> class A 
{ 
public: 
     void test() const 
     { 
       std::cout << "A!" << std::endl; 
     } 

     template<class U> friend A fun() 
     { 
       return A(); 
     } 
}; 

int main(int argc, char* argv[]) 
{ 
     A<double> aa; // 1 
     const auto& a = fun<int>(); 

     a.test(); 

     return 0; 
} 

Как я уже говорил, это работает для меня на GCC 4.8.1. Если я удалю (1), он терпит неудачу с следующий:

main.cpp: In function 'int main(int, char**)':                                          
main.cpp:20:18: error: 'fun' was not declared in this scope                                       
    const auto& a = fun<int>();                                              
       ^                                                
main.cpp:20:22: error: expected primary-expression before 'int'                                      
    const auto& a = fun<int>(); 

Я подозреваю, что UB здесь, но это будет очень интересно, если кто-нибудь может уточнить:

  1. Почему это на всех работах в то время как я не рассказать весело(), какую специализацию A он должен использовать?
  2. Если это не UB, какой тип T? Я попробовал type_info и нашел, что он не является ни int, ни double. typeid(). name() не помог, так как он возвращает «FdvE» для меня.
+0

Используйте C++ фильтрацию или какой-нибудь демон для вашего последнего беспокойства. на GCC я получаю 'double()'. –

+0

@remyabel. Конечно, 'T' не является типом функции;) – Columbo

ответ

0

Это похоже на ошибку GCC. friend шаблонов функций, которые определены в классе можно найти только с помощью ADL: НКУ, по-видимому считает aa во ADL для вызова в main (без причины) и называет A<double> «s fun, как это было подтверждено с помощью статического утверждения:

void test() const 
{ 
    static_assert(std::is_same<T, double>::value, ""); 
} 

Demo.
Clang делает not compile this code на всех.

Смежные вопросы