int()和int(*)()之间有什么区别?

5
我正在尝试创建一个类模板,用于识别函数,并在其中确定函数是否为特化了R (*)()的类模型,但是在std::function中,您可以声明return_type (),并且std::is_same<int(), int(*)()>.::value的值为零。这个int()语句是什么意思?int()int(*)()之间有什么区别? int()表示没有参数的函数,返回类型为int。 int(*)()表示一个指向没有参数的函数,返回类型为int的指针。 int(std::string::)()表示以std::string作为参数的函数,返回类型为int。 int std::string::()是无效的语法。 std::function是一个通用的函数包装器,它可以包装任何可调用对象,包括函数指针、成员函数指针、函数对象等等。 int(const std::string&)表示以const std::string&作为参数的函数,返回类型为int。
#include <iostream>
template<typename A,typename B>
struct IsSame{
  enum{
      value = 0};
};
template<typename A>
struct IsSame<A,A>{
    enum{
        value = 1  
    };
};
typedef int (SumType)(int,int)const;
class X{
  public:
        SumType sum;    
};
int X::sum(int a,int b)const{
    return a+b;
}

int main()
{
  std::cout << IsSame< int (const std::string&,int,int)const,
                       decltype( &X::sum)>::value;
}


3
一个是函数,另一个是指向函数的指针。 - HolyBlackCat
但是 int() 的用途是什么呢?因此,int() 是函数签名的声明,而 int(*)() 则是指向函数的指针。 - Diego Teixeira de Souza
1
还有一个非静态成员函数的等价物:int(int)&或int(int)const&的类型是什么? - Oliv
1
@Diego Teixeira de Souza int (std::string::*) () 是指向 std::string 类中一个不带参数且返回 int 的非静态成员函数的指针。我知道,这很疯狂。 - Zebrafish
1
Zebrafish是正确的。C++从C继承并扩展了其声明符语法,一直延续到“K&R”。其想法是使用接近使用点的语法。因此,int *f()是返回指向int的指针的函数,因为*f()是用于调用这样的函数并解除引用结果的内容。同样,int (*f)()是指向返回int的函数的指针,因为您首先会解除引用指针,然后调用函数(不要紧这第一步在语法上是可选的)。从内部向外读取声明符并考虑优先级,例如,int *a[4]是一个数组,而不是指针。 - Arne Vogel
1个回答

8
一个函数有一个类型,如void(),如果你取这个地址,你会得到一个指向该函数的指针void(*)()。它们不是相同的类型,尽管函数可以以类似数组衰变为指向第一个成员的指针的方式腐烂为指向函数的指针。
这意味着你可以声明一个函数:
void f();

并将其分配给一个指向相同签名的函数指针:

void (*p_to_f)() = f;

因此,我认为理解void()void(*)()之间的区别可能会很困难,但它们是不同的类型,在模板中这种区别可能很重要(在那里这种衰减不一定发生)。

当匹配模板特化时,衰减不发生的一个重要例子是考虑std::function的情况:

template <class>
class function;

template <class R, class ... Args>
class function<R(Args...)> { /* ... stuff ... */ };

专门针对函数类型的特化与针对指向函数类型的指针的特化不同。
function<void(int,int)> f;//matches specialisation
function<void(*)(int,int)> g;//does not match specialisation

回应原始评论(现已删除):
为了匹配指向函数的指针,您可以这样做:

template <class R, class ... Args>
function<R(*)(Args...)> : function<R(Args...>{};

这基本上意味着您将函数和指向函数的指针视为相同。如果您想匹配尽可能多的函数,还必须考虑成员函数、const成员函数和noexcept函数(截至C++17)。如果您想完全详细,还有&&&const &const&&volatile等...但除非它们实际出现,否则不要担心这些。


@DiegoTeixeiradeSouza 在模板特化中,是的,您将不得不分别对它们进行特化。 - SirGuy
但是仅针对 int() 进行专门处理更有意义。 - Diego Teixeira de Souza
1
这取决于你如何使用它,如果这来自一个decltype(f),其中f可以是任何东西,那么你必须关心差异。 - SirGuy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接