与 decltype 一起使用时的函数类型
function type when used with decltype
我正在研究 decltype
和 std::is_same_v
并尝试了它们的功能。
template<typename T>
void func(T t){}
template<typename T>
using f = decltype(func<T>);
template<typename T>
using ff = decltype((func<T>));
template<typename T>
using fff = void(*)(T);
template<typename T, typename U, typename Z>
void test(T t, U u, Z z){
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::cout << std::boolalpha
<< std::is_same_v<T, U> << " "
<< std::is_same_v<U, Z> << " "
<< std::is_same_v<Z, T>;
}
int main()
{
f<int> f1; // 1
ff<int> ff1 = func<int>; // 2
fff<int> fff1 = func<int>;
test(f1, ff1, fff1);
return 0;
}
输出:
void test(T, U, Z) [with T = void (*)(int); U = void (*)(int); Z = void (*)(int)]
true true true
在编辑时我错误地删除了参数和 运行 代码。 link to the demo
template<typename T, typename U, typename Z>
void test(T t, U u) // Z z is missing
{ // nothing changed in the body }
no matching function for call to 'test(void (&)(int), void (&)(int), void (*&)(int))'
36 | test(f1, ff1, fff1);
| ^
看起来 Z
是不同的类型,但 std::is_same_v<U, Z>
给出 true
。我认为 ff
和 f
根据 decltype
in cpprefernce
会是不同的类型
Note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression, thus decltype(x) and decltype((x)) are often different types.
- 当我尝试初始化时
f f1 = func<int>;
我收到警告和错误。
warning: declaration of 'void f1(int)' has 'extern' and is initialized
32 | f<int> f1 =func<int>;
| ^~
<source>:32:16: error: function 'void f1(int)' is initialized like a variable
32 | f<int> f1 =func<int>;
| ^~~~~~~~~
- 当我没有初始化时
ff ff1;
我收到一条错误消息
error: 'ff1' declared as reference but not initialized
33 | ff<int> ff1 ;
| ^~~
据我所知,由于 decltype((func<T>))
我得到了引用类型,但是 std::is_same_v
在 test
中给出了 true
。
Apparenlty,std::is_same_v
表明这三个相同但又不同。我是 c++ 的初学者,我无法理解发生了什么。
您的代码类似于:
f<int> f1; // `void f1(int);`, function declaration
ff<int> ff1 = func<int>; // `void (&ff1)(int) = func<int>;`, reference to function
fff<int> fff1 = func<int>; // `void (*fff1)(int) = &func<int>;` pointer to function,
// decay of `func<int>` to pointer
作为C数组,你不能按值传递函数;它们衰减为指针。
所以
test(f1, ff1, fff1); // test(&f1, &ff1, fff1);
在测试中,所有参数都有 void (*)(int)
类型。
我正在研究 decltype
和 std::is_same_v
并尝试了它们的功能。
template<typename T>
void func(T t){}
template<typename T>
using f = decltype(func<T>);
template<typename T>
using ff = decltype((func<T>));
template<typename T>
using fff = void(*)(T);
template<typename T, typename U, typename Z>
void test(T t, U u, Z z){
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::cout << std::boolalpha
<< std::is_same_v<T, U> << " "
<< std::is_same_v<U, Z> << " "
<< std::is_same_v<Z, T>;
}
int main()
{
f<int> f1; // 1
ff<int> ff1 = func<int>; // 2
fff<int> fff1 = func<int>;
test(f1, ff1, fff1);
return 0;
}
输出:
void test(T, U, Z) [with T = void (*)(int); U = void (*)(int); Z = void (*)(int)]
true true true
在编辑时我错误地删除了参数和 运行 代码。 link to the demo
template<typename T, typename U, typename Z>
void test(T t, U u) // Z z is missing
{ // nothing changed in the body }
no matching function for call to 'test(void (&)(int), void (&)(int), void (*&)(int))'
36 | test(f1, ff1, fff1);
| ^
看起来 Z
是不同的类型,但 std::is_same_v<U, Z>
给出 true
。我认为 ff
和 f
根据 decltype
in cpprefernce
Note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression, thus decltype(x) and decltype((x)) are often different types.
- 当我尝试初始化时
f f1 = func<int>;
我收到警告和错误。
warning: declaration of 'void f1(int)' has 'extern' and is initialized
32 | f<int> f1 =func<int>;
| ^~
<source>:32:16: error: function 'void f1(int)' is initialized like a variable
32 | f<int> f1 =func<int>;
| ^~~~~~~~~
- 当我没有初始化时
ff ff1;
我收到一条错误消息
error: 'ff1' declared as reference but not initialized
33 | ff<int> ff1 ;
| ^~~
据我所知,由于 decltype((func<T>))
我得到了引用类型,但是 std::is_same_v
在 test
中给出了 true
。
Apparenlty,std::is_same_v
表明这三个相同但又不同。我是 c++ 的初学者,我无法理解发生了什么。
您的代码类似于:
f<int> f1; // `void f1(int);`, function declaration
ff<int> ff1 = func<int>; // `void (&ff1)(int) = func<int>;`, reference to function
fff<int> fff1 = func<int>; // `void (*fff1)(int) = &func<int>;` pointer to function,
// decay of `func<int>` to pointer
作为C数组,你不能按值传递函数;它们衰减为指针。
所以
test(f1, ff1, fff1); // test(&f1, &ff1, fff1);
在测试中,所有参数都有 void (*)(int)
类型。