【问题标题】:C++ function typesC++ 函数类型
【发布时间】:2013-07-01 00:55:30
【问题描述】:

我在理解函数类型时遇到问题(例如,它们显示为 std::functionSignature 模板参数):

typedef int Signature(int); // the signature in question

typedef std::function<int(int)>  std_fun_1;
typedef std::function<Signature> std_fun_2;

static_assert(std::is_same<std_fun_1, std_fun_2>::value,
              "They are the same, cool.");

int square(int x) { return x*x; }

Signature* pf = square;   // pf is a function pointer, easy
Signature f;              // but what the hell is this?
f(42);                    // this compiles but doesn't link

变量f不能赋值,但可以调用。诡异的。那它有什么用呢?

现在,如果我对 typedef 进行 const 限定,我仍然可以使用它来构建更多类型,但显然没有其他用途:

typedef int ConstSig(int) const;

typedef std::function<int(int) const>  std_fun_3;
typedef std::function<ConstSig>        std_fun_4;

static_assert(std::is_same<std_fun_3, std_fun_4>::value,
              "Also the same, ok.");

ConstSig* pfc = square; // "Pointer to function type cannot have const qualifier"
ConstSig fc;            // "Non-member function cannot have const qualifier"

我在这里遇到了语言的哪个偏远角落?这种奇怪的类型是如何被调用的,我可以在模板参数之外使用它做什么?

【问题讨论】:

  • 该标准仅允许您通过 typedef 对其签名(实际上是函数类型)声明函数。

标签: c++ c++11 function-pointers std-function


【解决方案1】:

这是标准中的相关段落。它几乎不言自明。

8.3.5/10

函数类型的 typedef 可用于声明函数,但不得用于定义函数 (8.4)。

例子:

typedef void F();
F  fv;         // OK: equivalent to void fv();
F  fv { }      // ill-formed
void fv() { }  // OK: definition of fv

声明符包含 cv-qualifier-seq 的函数类型的 typedef 应仅用于声明非静态成员函数的函数类型,以声明一个函数类型。指向成员引用的指针,或声明另一个函数 typedef 声明的顶级函数类型。

例子:

typedef int FIC(int) const;
FIC f;               // ill-formed: does not declare a member function
struct S {
  FIC f;             // OK
};
FIC S::*pm = &S::f;  // OK

【讨论】:

  • 优秀。这正是我正在寻找的信息。谢谢。
  • 谢谢!我应该早点注意到的。
  • @Nik-Lz 确实,这不是很常见,但它也是其中没有充分理由明确禁止它的事情之一。另请注意,由于模板类型参数遵循与 typedef 大部分相同的规则,在std::function&lt;double(MyClass&amp;, int)&gt; 中,类模板std::function 本质上是使用函数 typedef。
【解决方案2】:

在您的情况下,std_fun_1std_fun_2 是具有相同类型签名的相同对象。它们都是std::function&lt;int(int)&gt;,都可以保存函数指针或int(int)类型的可调用对象。

pf 是指向int(int) 的指针。也就是说,它的基本用途与 std::function 相同,但没有该类的机制或对可调用对象实例的支持。

同样,std_fun_3std_fun_4 是具有相同类型签名的相同对象,并且都可以保存函数指针或 int(int) const 类型的可调用对象。

同样,pfcint(int) const 类型的函数指针,可以保存指向该类型函数的指针,但不能保存可调用对象的实例。

但是ffc函数声明。

行:

Signature fc;

等价于:

int fc(int) const;

这是一个名为 fc 类型为 int(int) const 的函数的声明。

这里没有什么奇怪的。从您不习惯的角度来看,您只是碰巧遇到了您可能已经理解的语法。

【讨论】:

    猜你喜欢
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 2011-06-07
    • 2018-04-23
    • 2010-11-21
    • 1970-01-01
    相关资源
    最近更新 更多