2016-09-29 3 views
5

Почему в качестве аргумента шаблона нельзя передать адрес std::cout? Или, если это возможно, то как?C++: & (std :: cout) в качестве аргумента шаблона

Вот что я пробовал:

#include <iostream> 

template<std::ostream* stream> 
class MyClass 
{ 
public: 
    void disp(void) 
     { (*stream) << "hello"; } 
}; 

int main(void) 
{ 
    MyClass<&(std::cout)> MyObj; 
    MyObj.disp(); 

    return 0; 
} 

И сообщение об ошибке я получил от clang++ -std=c++11:

main.cpp:15:11: error: non-type template argument does not refer to any declaration 
     MyClass<&(std::cout)> MyObj; 
       ^~~~~~~~~~~ 
main.cpp:6:24: note: template parameter is declared here 
template<std::ostream* stream> 
        ^
1 error generated. 

и от g++ -std=c++11:

main.cpp: In function ‘int main()’: 
main.cpp:15:22: error: template argument 1 is invalid 
    MyClass<&(std::cout)> MyObj; 
        ^
main.cpp:15:29: error: invalid type in declaration before ‘;’ token 
    MyClass<&(std::cout)> MyObj; 
          ^
main.cpp:16:8: error: request for member ‘disp’ in ‘MyObj’, which is of  non-class type ‘int’ 
    MyObj.disp(); 
     ^

Любые идеи?

+4

Почему вы заключили в скобки его? Также установите уровень доступа. – LogicStuff

+1

Попробуйте это без круглых скобок: MyClass <&std::cout> MyObj; ' – aschepler

+1

Я бы хотел получить объяснение, как это разбирается. – LogicStuff

ответ

2

Это исправляет код, опустить скобки:

#include <iostream> 

template<std::ostream* stream> 
class MyClass 
{ 
public: 
    void disp(void) { 
     (*stream) << "hello"; 
    } 
}; 

int main(void) 
{ 
    MyClass<&std::cout> MyObj; 
    MyObj.disp(); 

    return 0; 
} 

Live Demo


Более подробное объяснение, почему можно найти здесь:

Error with address of parenthesized member function

+0

Спасибо за ссылку! ;) –

+0

@GLorieul Обратите внимание, что '& std :: cout' вообще не является указателем на функцию, а адресом глобального экземпляра. –

+1

«Объяснение» является фиктивным. Мы не формируем указатель на участника здесь. –

5

Перед C + +17 удалено это ограничение, синтаксическая форма аргумент шаблона для параметра указателя или ссылочного шаблона был ограничен. N4140 [temp.arg.nontype] /1.3 говорит, что он должен быть

выражается (игнорируя круглые скобки), как &Ид выражение, где ID выражения этого имя объекта или функций , за исключением того, & может быть опущено, если имя относится к функции или массиву и должны быть опущены, если соответствующий шаблон-параметр представляет собой опорного

(std::cout) не является идентификатором . Это первичное выражение.

Часть «(без учета скобок)» была добавлена ​​Core issue 773 и, по-видимому, предназначена для разрешения (&i), а не &(i).

+0

Это слишком сложно для меня ... Что такое «синтаксическая форма»? –

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