我正在研究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
我在编辑时不小心删除了参数并运行了代码。 演示链接
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
。根据cppreference中对decltype
的描述,我认为ff
和f
应该是不同的类型。
请注意,如果对象的名称被括在括号中,它会被视为普通的左值表达式,因此
decltype(x)
和decltype((x))
通常是不同的类型。
- 当我尝试初始化
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>))
,我得到的是引用类型,但在test
中,std::is_same_v
返回了true
。
显然,std::is_same_v
告诉我们这三个都是相同的,但它们实际上是不同的。我是c++的初学者,无法理解发生了什么。
ff
可以看出,f
是一个函数指针(不确定),而ff
是一个引用类型的函数指针。这是否意味着当传递给函数时,它们总是像数组一样被衰减为指针? - TheScoretest()
函数时,既非ff
也非f
最初是指针类型(尽管fff
是),f
是值类型,而ff
是引用类型,但两者在传递到test()
时都会衰减为指针。 - Patrick Robertsstd::is_same_v
放在主函数里。std::is_same_v<void(int), f<int>>
->true
...std::is_same_v<void(&)(int), ff<int>>
->true
...std::is_same_v<void(*)(int), fff<int>>
->true
。希望我所有的类型都是正确的。请考虑添加一个答案。我会接受它。再次感谢您的时间和耐心。 - TheScoref f1 = func<int>;
给出的错误,这是什么意思呢? - TheScore