Это потому, что нет никакой разницы между
Foo<double(double)>(sin);
и
Foo<double(double)> sin;
Оба объявляют переменную имени sin
.
Парены лишние,Вы можете поставить столько паренов, сколько захотите.
int x; //declares a variable of name x
int (x); //declares a variable of name x
int ((x)); //declares a variable of name x
int (((x))); //declares a variable of name x
int (((((x))))); //declares a variable of name x
Все одинаковы!
Если вы хотите создать временный экземпляр класса, передавая sin
в качестве аргумента для конструктора, затем сделайте следующее:
#include<iostream>
#include <cmath>
template<typename F>
struct Foo { Foo(F) { std::cout << "called" << std::endl; } };
int main()
{
(void)Foo<double(double)>(sin); //expression, not declaration
(Foo<double(double)>(sin)); //expression, not declaration
(Foo<double(double)>)(sin); //expression, not declaration
}
Вывод:
called
called
called
Демо: http://ideone.com/IjFUe
Они работают, потому что все три синтаксиса заставляют ихбыть выражениями, а не объявлениями переменных .
Однако, если вы попробуете это (как @fefe предложено в комментарии):
Foo<double(double)>(&sin); //declaration, expression
Это не сработает, так как объявляет ссылочную переменную, и поскольку это не такинициализированный, вы получите ошибку компиляции.Смотри: http://ideone.com/HNt2Z