【发布时间】:2020-07-20 22:32:05
【问题描述】:
我的示例代码在 GCC/Clang/MSVC 上可以在 C++14 下编译,在 Clang/MSVC 上可以在 C++17 下编译,但在 GCC 8.x 到 10.1 上的 C++17 下会产生错误.
#include <vector> // vector
template< typename Seq,
typename Seq::value_type& ( Seq::*next )(),
void ( Seq::*pop )() >
void f( Seq& );
template< typename Seq >
void g( Seq& seq )
{
f< Seq, &Seq::back, &Seq::pop_back >( seq );
}
void foo()
{
std::vector< int > v;
g( v );
}
我使用 CXXFLAGS=-std=c++17 从 GCC 10.1 收到以下错误:
<source>: In instantiation of 'void g(Seq&) [with Seq = std::vector<int>]':
<source>:17:10: required from here
<source>:11:41: error: no matching function for call to 'f<std::vector<int, std::allocator<int> >, (& std::vector<int, std::allocator<int> >::back), &std::vector<int, std::allocator<int> >::pop_back>(std::vector<int>&)'
11 | f< Seq, &Seq::back, &Seq::pop_back >( seq );
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
<source>:6:6: note: candidate: 'template<class Seq, typename Seq::value_type& (Seq::* next)(), void (Seq::* pop)()> void f(Seq&)'
6 | void f( Seq& );
| ^
<source>:6:6: note: template argument deduction/substitution failed:
<source>:11:41: error: 'int& (std::vector<int>::*)(){((int& (std::vector<int>::*)())std::vector<int>::back), 0}' is not a valid template argument for type 'int& (std::vector<int>::*)()'
11 | f< Seq, &Seq::back, &Seq::pop_back >( seq );
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
<source>:11:41: note: it must be a pointer-to-member of the form '&X::Y'
Compiler returned: 1
我知道第二个参数,&Seq::back是一个重载函数;我创建了一个非常量重载的中间成员函数指针,并将其作为第二个参数传递给调用f,但我收到几乎相同的错误。
所以,基本问题是,这是无效的 C++17 代码,还是 GCC 错误?假设它是无效的 C++17,我将如何使它有效?
额外问题:'int& (std::vector<int>::*)(){((int& (std::vector<int>::*)())std::vector<int>::back), 0}' 是什么?我对{/} 和0 感到非常惊讶。我知道外部是方法签名,内部的第一部分是将重载的方法转换为预期的签名,但是为什么{/} 对和0?初始化列表?一个结构?成员指针的内部结构?
【问题讨论】:
标签: c++ gcc c++17 overloading function-templates