c++ - 与 decltype 一起使用时的函数类型

标签 c++ decltype is-same

我正在调查 decltypestd::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;
}
link to the demo
输出:
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 .我想fff根据 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给了 truetest .
    外观,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)类型。

    关于c++ - 与 decltype 一起使用时的函数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67240617/

    相关文章:

    c++ - 如何在模板参数中将 std::result_of 转换为 decltype

    c++ - std::is_same 在类型相等性检查上的荒谬行为

    c++ - Google 测试 (gtest) `EXPECT_TRUE()` 宏不会使用 `std::is_same<>` 模板作为输入进行编译

    c++ - 使用自定义着色器在全屏四边形上从 QGLFramebufferObject 绘制纹理

    c++ - alt-tab 中的 WS_EX_TOOLWINDOW

    c++ 为什么 decltype(*pointer) 产生一个引用?

    c++ - 基于模板参数的条件编译时类型映射

    c++ - 如何让一个变量依赖于一个类中的其他变量?

    c++ - 编译器无法推断返回类型?