【问题标题】:pre-typedef'ing a variadic-function-pointer argument预先定义可变参数函数指针参数
【发布时间】:2015-09-22 10:07:17
【问题描述】:

我有一个函数foo,它接受一个可变函数指针作为它的参数。

我想在函数声明之前使用“using”来定义参数的类型。

template <typename ... vARGS>
using TFuncType = void(*)(vARGS ... V_args);

template <typename ... vARGS>
void foo(TFuncType<vARGS ...> funcptr) {}

void bar(int i) {}

int main() {
  foo(&bar); // This line fails to compile.
}

这不会编译。错误(使用c++1z通过clang)是:

/make/proj/test/variadic-funcparam-deduce2.cpp:39:5: error: no matching function for call to 'foo'
foo(&bar);
^~~
/make/proj/test/variadic-funcparam-deduce2.cpp:33:36: note: candidate template ignored: substitution failure [with vARGS = int]
template <typename ... vARGS> void foo(TFuncType<vARGS ...> funcptr) {}

为什么“int”替换失败?

如果我在 foo() 中显式写入类型,我可以成功编译:

template <typename ... vARGS>
void foo(void(*funcptr)(vARGS ... V_args)) {}

但即使显式指定模板参数并为参数使用预制的TFuncType&lt;int&gt;,我也无法使初始(“使用”)版本工作,即:

int main() {
  TF_call<int> fptr = &bar; // This line is OK.
  foo<int>(fptr);
}

有人知道这里有什么吗?

使用 typedef'd ("using") 可变参数和/或我遗漏的函数指针有什么奇怪的地方吗?

【问题讨论】:

  • 与 GCC 一起工作,我想不出这段代码会破坏任何规则,所以我打算解决一个 Clang 错误。
  • 好的,我会放一个小时左右,如果没有进一步的 cmets,我会提交一个错误报告。谢谢。
  • 我通过 -std=c++14 通过 clang 3.6 发送了这个,没有问题。仅供参考,Apple LLVM 版本 6.1.0 (clang-602.0.53)(基于 LLVM 3.6.0svn)
  • 现在只更新主干,以便在报告前重新测试。我认为它大约 2 个月大,但目前有点难以检查。我相信它是 3.7.0,通过主干。
  • 这绝对是 Clang 的 bug;在此代码上的 Clang 断言的调试版本。

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


【解决方案1】:

我相信这可能与我从 this answer 复制的以下文本有关,该文本本身取自 14.5.7 [temp.alias] 第 2 段中的 C++ 标准:

当模板ID 指代一个别名模板的特化时, 它等效于通过替换获得的关联类型 它的模板参数在 type-id 中的模板参数 别名模板。 [ 注意:永远不会推断出别名模板名称。 — 尾注]

如果我的解释是正确的,这意味着接受代码的 GCC 实际上是不合格的。

【讨论】:

  • 是的,我现在很确定这是非法的。您的 sn-p 似乎可以解释它,谢谢。
  • 我不太确定。它说别名模板 name 永远不会被推导出来。它不是推导出名称,因为名称已经在模板函数的声明中给出。只有当您的模板需要 template template 参数时,该警告似乎才适用。见the cppreference example
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-25
  • 1970-01-01
相关资源
最近更新 更多