问题
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?
回答1:
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>);
@T.C. 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++.
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/44766581/what-type-is-intint-or-intint-const