【问题标题】:Why isn't std::function a valid template parameter while a function pointer is?为什么 std::function 不是有效的模板参数,而函数指针是?
【发布时间】:2012-11-19 15:05:02
【问题描述】:

我已经定义了名为CallBackAtInit 的类模板,其唯一目的是在其初始化时调用一个函数(构造函数)。该函数在模板参数中指定。问题是模板不接受std::function 作为参数;但他们接受函数指针。为什么?

这是我的代码:

#include <iostream>
#include <functional>

/* Does not work:*/     template <typename return_type, typename arg_type, std::function<return_type(arg_type)> call_back>
/* Work fine: *///      template <typename return_type, typename arg_type, return_type(*call_back)(arg_type)>

class CallBackAtInit {
public:
    CallBackAtInit(arg_type arg)
    {
        call_back(arg);
    };
};

void printInt(int i);

class HoldInt : private CallBackAtInit<void, int, printInt> {
public:
    HoldInt(int integer)
    : CallBackAtInit(integer)
    {}
    // ...
};

int main(int argc, char** argv)
{
    HoldInt hi(10);
    return 0;
}

void printInt(int i)
{
    std::cout << i << std::endl;
}

【问题讨论】:

  • 你能发布你的编译错误吗?
  • @Jean-Marie 不走寻常路。 main.cpp:4:115:错误:'struct std::function' 不是模板常量参数的有效类型
  • 我认为您应该更新您的问题标题和/或正文,以明确您指的是 non-type 参数。 std::function 是一个有效的模板参数,即&lt;typename std::function&lt;()&gt;&gt;,它只是作为非类型参数无效

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


【解决方案1】:

模板定义的参数可以有四种:

  • 只能接受type(或template类型)的参数。
  • 只能接受整数值的参数。
  • 只能接受指向成员值的指针的参数。
  • std::nullptr_t (C++11 起)

当您在模板定义中提及std::function 时,它既不属于上述类别。模板不能接受types,也不能接受integral value,或者pointer-to-member value。

如果参数是函数指针类型,那么它可以接受函数指针(与类型匹配的函数的地址),它只是一个整数值。请注意,地址始终是一个整数值。所以它属于第二类,这就是它起作用的原因。

【讨论】:

  • -1,还有其他允许的非类型模板参数形式。指向成员的指针是整数类型吗? nullptr_t 是整数类型吗?引用是整数类型吗?
  • @JonathanWakely:已编辑。 pointer-to-member 类型只是跳过了我的想法。我没想到nullptr_t。
【解决方案2】:

因为标准不允许:

14.1 模板参数

4 非类型模板参数应具有以下之一 (可选 cv 限定)类型:

——整数或枚举类型,

——指向对象的指针或指向函数的指针,

——对对象的左值引用或对函数的左值引用,

——指向成员的指针,

——std::nullptr_t。

【讨论】:

  • +1 但最好解释一下为什么只允许这些类型。原因是这些类型的值可以在编译时知道,当模板被处理时。 std::function&lt;F&gt; 之类的非平凡类型在编译时没有已知的常量值,std::string 之类的类型也没有
  • 如果不投反对票,我就无法阅读这个答案。提问者已经知道它在 C++ 中是无效的。他说“为什么 std::function 不是一个有效的模板参数,而函数指针是一个有效的模板参数?”。告诉他不允许这样做有什么帮助?很幸运,@JonathanWakely 比我更宽容。
  • @JohannesSchaub-litb,其实还有很多类型可以在编译/链接时将值已知到表示的最后一位,例如浮点数或任何类型的笛卡尔积,已经在列表中,又名结构,其中可能还包括 std::function 的实例,所以,严格来说,答案是“为什么?”是“只是因为!”。
  • 如果您将该评论放在您的答案中,我不会投反对票:-)
  • @JohannesSchaub-litb,呵呵,反正... :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
相关资源
最近更新 更多