return 类型的 decltype(function_name) 完全没用?
the return type of decltype(function_name) is totally useless?
void foo(int a) {
cout << "Hello" << a << '\n';
}
根据decltype的规则,decltype(foo)的类型应该是"void foo(int)",
但似乎我们对此无能为力:
void (& f_ref)(int) = foo;
void (* f_ptr)(int) = foo;
cout<<is_same_v<decltype(foo), decltype(f_ref)><<endl; //return 0
cout<<is_same_v<decltype(foo), decltype(f_ptr)><<endl; //return 0
decltype(foo) df;
df = foo; //error: assignment of function ‘void df(int)’
df = &foo; //error: assignment of function ‘void df(int)’
decltype(foo) df{foo}; //error: function ‘void df(int)’ is initialized like a variable
decltype(foo) df{&foo}; //error: function ‘void df(int)’ is initialized like a variable
您可以使用它来声明与函数具有相同签名的函数对象:
using ffoo = ::std::function<decltype(foo)>;
这正是它应该的样子。如果你写void(int) df;
,那显然是错误的。您正试图声明一个函数类型的变量,这没有意义。这可能有意义的唯一上下文是声明一个函数对象:auto bar = std::function<decltype(foo)>;
现在 bar
是一个对象,它引用类型为 void(int)
的函数(或 function-like 实例,例如 lambda)。
声明一个变量:
decltype(foo)* pf = foo;
pf(42);
使用 std::function
函数包装器:
std::function<decltype(foo)> f = foo;
f(42);
Is the return type of decltype(function_name) totally useless?
绝对不是。 Live example
void f1();
void f2(int);
void f3();
int main()
{
std::cout << "f1 - f2 " << std::is_same<decltype(f1),decltype(f2)>::value << std::endl;
std::cout << "f1 - f3 " << std::is_same<decltype(f1),decltype(f3)>::value << std::endl;
}
例如,这可以与 std::enable_if
一起使用。
您的代码段中的两个 is_same_v
被评估为 0
因为类型不同。
dectype(foo)
是void (int)
(不是void foo(int)
,名称不是类型的一部分),
不同于void (&)(int)
(f_ref
的类型)和void (*)(int)
(f_ptr
的类型)。
这一行:
decltype(foo) df{foo};
不能编译只是因为语法不允许你在函数声明中有初始值设定项。
即使没有 decltype
它也不起作用:
void df(int) {foo}; // error: expected ';' before '}' token
尽管您可以创建指向 decltype(foo)
的指针:
decltype(foo) *df{foo}; // Becomes `void (*df)(int) {foo};`
这些行:
df = foo;
df = &foo;
不要编译,因为你不能赋值给函数。即使 df
是 void df(int);
.
也行不通
如何使用这种类型?
有无数的用途。例如。您可以使用它来创建指向此函数的指针,如上所述,或者它可以用作模板参数(用于 std::function
或其他)。
在此声明中
cout<<is_same_v<decltype(foo), decltype(f_ref)><<endl;
左边的模板参数是函数类型,右边的模板参数是引用类型。要比较类型,您应该删除引用。
在此声明中
cout<<is_same_v<decltype(foo), decltype(f_ptr)><<endl;
比较函数类型和函数指针。
因此这两个语句 returns 0 (false).
这些语句
df = foo;
df = &foo;
没有意义。您不能分配功能。
以及这些陈述
decltype(foo) df{foo};
decltype(foo) df{&foo};
也说不通。
您可以在 class 中声明类型为 decltype( foo )
的函数,然后定义它。
这是一个演示程序。
#include <iostream>
#include <type_traits>
void foo( int a )
{
std::cout << "Hello " << a << '\n';
}
struct A
{
decltype(foo) df;
};
void A::df( int a )
{
std::cout << "Bye " << a << '\n';
}
int main()
{
foo( 0 );
A a;
a.df( 1 );
void (& f_ref)(int) = foo;
void (* f_ptr)(int) = foo;
std::cout << std::is_same<decltype(&foo), decltype( f_ptr )>() << std::endl;
std::cout << std::is_same<decltype(foo), std::remove_reference_t<decltype( f_ref )>>() << std::endl;
return 0;
}
它的输出是
Hello 0
Bye 1
1
1
在此声明中考虑到这一点
void (& f_ref)(int) = foo;
函数指示符 foo
隐式转换为指向函数的指针。
void foo(int a) {
cout << "Hello" << a << '\n';
}
根据decltype的规则,decltype(foo)的类型应该是"void foo(int)", 但似乎我们对此无能为力:
void (& f_ref)(int) = foo;
void (* f_ptr)(int) = foo;
cout<<is_same_v<decltype(foo), decltype(f_ref)><<endl; //return 0
cout<<is_same_v<decltype(foo), decltype(f_ptr)><<endl; //return 0
decltype(foo) df;
df = foo; //error: assignment of function ‘void df(int)’
df = &foo; //error: assignment of function ‘void df(int)’
decltype(foo) df{foo}; //error: function ‘void df(int)’ is initialized like a variable
decltype(foo) df{&foo}; //error: function ‘void df(int)’ is initialized like a variable
您可以使用它来声明与函数具有相同签名的函数对象:
using ffoo = ::std::function<decltype(foo)>;
这正是它应该的样子。如果你写void(int) df;
,那显然是错误的。您正试图声明一个函数类型的变量,这没有意义。这可能有意义的唯一上下文是声明一个函数对象:auto bar = std::function<decltype(foo)>;
现在 bar
是一个对象,它引用类型为 void(int)
的函数(或 function-like 实例,例如 lambda)。
声明一个变量:
decltype(foo)* pf = foo;
pf(42);
使用 std::function
函数包装器:
std::function<decltype(foo)> f = foo;
f(42);
Is the return type of decltype(function_name) totally useless?
绝对不是。 Live example
void f1();
void f2(int);
void f3();
int main()
{
std::cout << "f1 - f2 " << std::is_same<decltype(f1),decltype(f2)>::value << std::endl;
std::cout << "f1 - f3 " << std::is_same<decltype(f1),decltype(f3)>::value << std::endl;
}
例如,这可以与 std::enable_if
一起使用。
您的代码段中的两个 is_same_v
被评估为 0
因为类型不同。
dectype(foo)
是void (int)
(不是void foo(int)
,名称不是类型的一部分),
不同于void (&)(int)
(f_ref
的类型)和void (*)(int)
(f_ptr
的类型)。
这一行:
decltype(foo) df{foo};
不能编译只是因为语法不允许你在函数声明中有初始值设定项。
即使没有 decltype
它也不起作用:
void df(int) {foo}; // error: expected ';' before '}' token
尽管您可以创建指向 decltype(foo)
的指针:
decltype(foo) *df{foo}; // Becomes `void (*df)(int) {foo};`
这些行:
df = foo;
df = &foo;
不要编译,因为你不能赋值给函数。即使 df
是 void df(int);
.
如何使用这种类型?
有无数的用途。例如。您可以使用它来创建指向此函数的指针,如上所述,或者它可以用作模板参数(用于 std::function
或其他)。
在此声明中
cout<<is_same_v<decltype(foo), decltype(f_ref)><<endl;
左边的模板参数是函数类型,右边的模板参数是引用类型。要比较类型,您应该删除引用。
在此声明中
cout<<is_same_v<decltype(foo), decltype(f_ptr)><<endl;
比较函数类型和函数指针。
因此这两个语句 returns 0 (false).
这些语句
df = foo;
df = &foo;
没有意义。您不能分配功能。
以及这些陈述
decltype(foo) df{foo};
decltype(foo) df{&foo};
也说不通。
您可以在 class 中声明类型为 decltype( foo )
的函数,然后定义它。
这是一个演示程序。
#include <iostream>
#include <type_traits>
void foo( int a )
{
std::cout << "Hello " << a << '\n';
}
struct A
{
decltype(foo) df;
};
void A::df( int a )
{
std::cout << "Bye " << a << '\n';
}
int main()
{
foo( 0 );
A a;
a.df( 1 );
void (& f_ref)(int) = foo;
void (* f_ptr)(int) = foo;
std::cout << std::is_same<decltype(&foo), decltype( f_ptr )>() << std::endl;
std::cout << std::is_same<decltype(foo), std::remove_reference_t<decltype( f_ref )>>() << std::endl;
return 0;
}
它的输出是
Hello 0
Bye 1
1
1
在此声明中考虑到这一点
void (& f_ref)(int) = foo;
函数指示符 foo
隐式转换为指向函数的指针。