【问题标题】:Function pointers as template arguments函数指针作为模板参数
【发布时间】:2018-07-24 15:21:03
【问题描述】:

在以下 C++ 代码中,bar<func_ptr>(); //does not work 行导致编译错误:

#include <iostream>

using namespace std;

void foo(){
    cout<<"Hello world";
};

template<void(*func)()> 
void bar(){
    (*func)();
}

int main() {
    using fun_ptr_type= void(*)();
    constexpr fun_ptr_type func_ptr=&foo;

    bar<&foo>();     //works
    bar<func_ptr>(); //does not work
    return 0;
}

g++的输出是这样的:

src/main.cpp: In function ‘int main()’:
src/main.cpp:19:16: error: no matching function for call to ‘bar()’
  bar<func_ptr>(); //does not work
                ^
src/main.cpp:10:6: note: candidate: template<void (* func)()> void bar()
 void bar(){
      ^~~
src/main.cpp:10:6: note:   template argument deduction/substitution failed:
src/main.cpp:19:16: error: ‘(fun_ptr_type)func_ptr’ is not a valid template argument for ty
pe ‘void (*)()’
  bar<func_ptr>(); //does not work
                ^
src/main.cpp:19:16: error: it must be the address of a function with external linkage

我不明白为什么当我直接将foo 的地址作为模板参数传递时它会起作用,但是当我传递 constexpr func_ptr 时,代码不再编译,即使它恰好包含 @987654328 的地址@ 在编译时。谁能给我解释一下?

编辑:我的 g++ 版本是

$ g++ --version
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【问题讨论】:

  • 没有 gcc8 和 clang6 的复制。
  • 按预期工作Here (C++17)。
  • C++14 出错Demo
  • 我记得自 C++11 以来,关于指向全局变量和 constexpr 文字的指针对模板参数有效的一些变化。但我不记得这是否是其中一种情况,也不记得如何找到它。
  • 与 Jarod42 的体验相同。 C ++ 17 它可以工作; C++14 吐出一个错误。

标签: c++ templates function-pointers


【解决方案1】:

来自https://en.cppreference.com/w/cpp/language/template_parameters 它说:

对于指向函数的指针,有效参数是指向具有链接的函数的指针(或计算为空指针值的常量表达式)。 (直到 C++17)。

由于constexpr fun_ptr_type func_ptr=&amp;foo 在编译时不会评估为nullptr 值,因此如果使用-std=c++14-std=c++11 运行它会失败。

但是 C++17 对函数指针非类型模板参数没有这样的要求。它说:

可与非类型模板形参一起使用的模板实参可以是模板形参类型的任何转换常量表达式。 (C++17 起)

(上面有一些例外,但没有一个适用于函数指针)。

因此,您提供的代码可以在 -std=c++17 选项下完美运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 2021-12-10
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多