【问题标题】:g++ and clang++ different behaviour with pointer to variadic template functionsg++ 和 clang++ 不同的行为与指向可变参数模板函数的指针
【发布时间】:2018-07-15 20:24:57
【问题描述】:

另一个“在 g++ 和 clang++ 之间谁是对的?” C++ 标准大师的问题。

代码如下

template <typename ...>
struct bar
 { };

template <typename ... Ts>
void foo (bar<Ts...> const &)
 { }

int main ()
 {
   foo<int>(bar<int, long>{});     // g++ and clang++ compile

   (*(&foo<int>))(bar<int, long>{});  // g++ and clang++ give error

   (&foo<int>)(bar<int, long>{});  // clang++ compiles; g++ gives error
 }

模板函数foo()接收可变参数模板参数bar。

第一次通话

   foo<int>(bar<int, long>{});     // g++ and clang++ compile

适用于 clang++ 和 g++。

如果我理解正确,foo&lt;int&gt; 被解释为仅第一个模板参数,这并没有完成Ts... 参数的列表。因此编译器查看参数(bar&lt;int, long&gt; 对象)并推导出完整列表。

第二次调用不同

     (*(&foo<int>))(bar<int, long>{});  // g++ and clang++ give error

如果我理解正确,使用(&amp;foo&lt;int&gt;) 我们会得到指向foo 实例化的指针,其中Ts... 正是int(不仅是列表的第一种类型,而且是整个列表)并取消引用它( *(&amp;foo&lt;int&gt;)) 并使用错误的参数(bar&lt;int, long&gt; 对象)调用它,我们得到(clang++ 和 g++)编译错误。

到目前为止,一切都很好。

问题出现在第三次调用

   (&foo<int>)(bar<int, long>{});  // clang++ compiles; g++ gives error

我确信(也许我错了)相当于第二个(我们修复了Ts... 中的所有模板类型,然后我们用错误的参数调用函数)但是 g++ 似乎同意(并给出错误)clang++ 不同意(并且编译没有问题)。

和往常一样,问题是:谁是对的?

【问题讨论】:

  • VC++ 2017 不编译其中任何一个。

标签: c++ c++11 templates variadic-templates template-argument-deduction


【解决方案1】:

让我们来看看一个更简单的例子:

template <class A, class B>void foo(B) {};

int main()
{
    (&foo<char>)(1);
}

clang++ 编译它,而 g++ 失败并显示以下消息:

错误:没有上下文类型信息的重载函数地址

给出了相同的消息,例如这个程序:

void moo(int) {};
void moo(int*){};

int main()
{
    &moo != nullptr;
}

显然,其意图是引用[over.over],它谈论的是获取重载函数的地址。标准中的这个位置指定了可以在哪些上下文中使用重载函数名称(赋值的 RHS、函数调用中的参数等)。但是它说

重载的函数名不应不带参数在所列上下文之外的上下文中使用。 (强调我的)

现在,(&amp;foo&lt;char&gt;)(1) 中的foo 是否不带参数使用? g++ 似乎下沉了。但是它可以愉快地编译

(&moo)(1);

来自第二个例子。所以我们在这里至少有一些不一致之处。相同的规则适用于获取函数模板和重载集的地址,因此(&amp;foo&lt;char&gt;)(1) 和(&amp;moo)(1) 应该都有效或无效。标准本身似乎表明它们都应该是有效的:

重载函数名前面可以有 & 运算符 [...] [注意:任何围绕重载函数名的多余括号都将被忽略 (5.1)。 — 尾注]

【讨论】:

    猜你喜欢
    • 2013-04-30
    • 1970-01-01
    • 2017-10-20
    • 2015-01-19
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多