简体   繁体   中英

What type is int(int)& or int(int) const &?

std::is_function is specialized for types which have signature similar to:

int(int) &

see here: std::is_function

But this is neither a pointer to a member method, which signature could be:

int(T::*)(int) &

Nor it can be a reference to a function:

int (&)(int)

So what is this strange signature?

It's a function type which only exists in the type system. It cannot ever be created.

But this is neither a pointer to a member method, which signature could be:

 int(T::*)(int) & 

It's this, without the pointer. The type system allows you to describe that as a type.

#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>);

@TC mentions PR0172R0 , which discusses how the presence of these types causes issues for library writers, and suggests several options which might reduce those issues. One of the options is getting rid of them entirely, others reduce their impact. Depending on how this goes, this answer may or may not be correct for future versions of C++.

On the documentation page you link to, you'll see this comment:

// specialization for function types that have ref-qualifiers

above the list the examples you reference come from.

Those are functions with ref-qualifiers, which you can read more about here .

In short, they are similar to const qualified functions. Here's an example:

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;
}

I can't think of a great use case for this feature, but it is possible to use.

Since the beginning of times (referring to the first C++ standard) you could declare such "strange" function types as, for example

typedef int F() const;

Despite the fact that the above declaration does not immediately involve any classes, the trailing const in this case can only serve as const-qualification of a non-static class member function. This restricts the usage of the above typedef-name to class member declarations. For example, one could use it as follows

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

Note that, however obscure, this is a "classic" C++ feature that's been in the language for a long time.

What you have in your example is effectively the same thing, but with C++11 ref-qualifier in place of const qualifier.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM