繁体   English   中英

g ++和clang ++使用指向可变参数模板函数的指针的不同行为

[英]g++ and clang++ different behaviour with pointer to variadic template functions

另一个“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 ++ ang g ++。

如果我理解正确,与foo<int>是阐明只有第一个模板参数,这不完全名单Ts...参数。 因此编译器会查看参数( bar<int, long>对象)并推导出完整列表。

第二个电话是不同的

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

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

到现在为止还挺好。

问题出现在第三次电话会议上

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

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

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

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

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,函数调用中的参数等)。 然而它说

如果没有参数 ,则不应在除列出的上下文之外的上下文中使用重载的函数名称。 (强调我的)

现在, foo in (&foo<char>)(1) 没有参数 g ++似乎沉沦了。 然而它很乐意编译

(&moo)(1);

从第二个例子。 所以我们在这里至少有一些不一致。 采用相同的规则来控制函数模板和重载集的地址,因此(&foo<char>)(1)(&moo)(1)应该既有效又无效。 标准本身似乎表明嘿应该都是有效的:

重载函数名称可以在&运算符[...]之前[ 注意 :忽略重载函数名称周围的任何多余括号(5.1)。 - 结束说明 ]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM