什么类型是int(int)&或int(int)const&?

Oli*_*liv 6 c++ types declaration

std::is_function 专门用于具有类似于以下特征的类型的类型:

int(int) &
Run Code Online (Sandbox Code Playgroud)

看到这里:std :: is_function

但这既不是指向成员方法的指针,哪个签名可能是:

int(T::*)(int) &
Run Code Online (Sandbox Code Playgroud)

它也不是对函数的引用:

int (&)(int)
Run Code Online (Sandbox Code Playgroud)

那个奇怪的签名是什么?

小智 13

它是一种仅存在于类型系统中的函数类型.它永远不会被创造出来.

但这既不是指向成员方法的指针,哪个签名可能是:

int(T::*)(int) &
Run Code Online (Sandbox Code Playgroud)

就是这样,没有指针.类型系统允许您将其描述为类型.

#include <type_traits>

struct T { };
using A = int(int) &;
using B = A T::*;
using C = int(T::*)(int) &;

static_assert(std::is_same_v<B, C>);
Run Code Online (Sandbox Code Playgroud)

@TC提到PR0172R0,它讨论了这些类型的存在如何给库编写者带来问题,并提出了几个可能减少这些问题的选项.其中一个选择是完全摆脱它们,其他选择减少它们的影响.根据具体情况,这个答案可能适用于未来的C++版本,也可能不正确.

  • 我将链接到[P0172R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0172r0.html)中的精彩摘要. (3认同)
  • 我相信你也可以`使用A = int(int)&; struct Bob {A foo; };`. (3认同)

SJL*_*SJL 6

在您链接到的文档页面上,您会看到以下评论:

// specialization for function types that have ref-qualifiers
Run Code Online (Sandbox Code Playgroud)

在列表上方,您引用的示例来自.

这些是具有ref-qualifiers的函数,您可以在这里阅读更多信息.

简而言之,它们与const合格的功能类似.这是一个例子:

struct foo
{
    void bar() & { std::cout << "this is an lvalue instance of foo" << "\n"; }
    void bar() && { std::cout << "this is an rvalue instance of foo" << "\n"; }
};

int main(int argc, char* argv[])
{
    foo f{};
    f.bar();            // prints "this is an lvalue instance of foo"
    std::move(f).bar(); // prints "this is an rvalue instance of foo"

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我无法想到这个功能的一个很好的用例,但它可以使用.


AnT*_*AnT 5

从一开始(指第一个C++标准),您可以声明这样的"奇怪"函数类型,例如

typedef int F() const;
Run Code Online (Sandbox Code Playgroud)

尽管上述声明不会立即涉及任何类,但const在这种情况下,尾部只能作为非静态类成员函数的const限定.这限制了上述typedef-name对类成员声明的使用.例如,可以如下使用它

struct S {
  F foo;              // Declares an `int S::foo() const` member function
};

int S::foo() const {  // Defines it
  return 42;
}

F S::*p = &S::foo;    // Declares 'p' as `int (S::*)() const` pointer
Run Code Online (Sandbox Code Playgroud)

请注意,无论多么模糊,这都是一种"经典"C++功能,该功能已经在语言中使用了很长时间.

您的示例中的内容实际上是相同的,但使用C++ 11 ref-qualifier代替const限定符.