#include <utility>
#include <iostream>
struct Data {
uint8_t m_x;
double m_y;
uint32_t m_z;
Data(uint8_t x, double y, uint32_t z) : m_x(x), m_y(y), m_z(z) {
std::cout << "constructor called" << std::endl;
}
};
template <class Data, typename... Args>
class Layer1 {
public:
void foo(Args&&... args) {
Data(std::forward(args)...);
}
};
int main() {
Layer1<Data, uint8_t, double, uint32_t> layer1;
layer1.foo(1, 1.1, 2);
}
当我编译上面的代码时,gcc 8.2输出:
$ g++ -Wall test_forward.cpp -o test_forward -O3 -std=c++17
test_forward.cpp: In instantiation of ‘void Layer1<Data, Args>::foo(Args&& ...) [with Data = Data; Args = {unsigned char, double, unsigned int}]’:
test_forward.cpp:39:22: required from here
test_forward.cpp:31:16: warning: unused variable ‘layer2’ [-Wunused-variable]
Layer2<Data> layer2;
^~~~~~
[hchan@heilinux cpp]$ g++ -Wall test_forward.cpp -o test_forward -O3 -std=c++17
[hchan@heilinux cpp]$ g++ -Wall test_forward.cpp -o test_forward -O3 -std=c++17
test_forward.cpp: In instantiation of ‘Layer1<Data, Args>::MyData::MyData(Args&& ...) [with Data = Data; Args = {unsigned char, double, unsigned int}]’:
test_forward.cpp:32:3: required from ‘void Layer1<Data, Args>::foo(Args&& ...) [with Data = Data; Args = {unsigned char, double, unsigned int}]’
test_forward.cpp:39:22: required from here
test_forward.cpp:27:51: error: no matching function for call to ‘forward(unsigned char&)’
MyData(Args&&... args) : i(0), data(std::forward(args)...) {}
~~~~~~~~~~~~^~~~~~
In file included from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/stl_pair.h:59,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/utility:70,
from test_forward.cpp:1:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/move.h:74:5: note: candidate: ‘template<class _Tp> constexpr _Tp&& std::forward(typename std::remove_reference<_Tp>::type&)’
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
^~~~~~~
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/move.h:74:5: note: template argument deduction/substitution failed:
test_forward.cpp:27:51: note: couldn't deduce template parameter ‘_Tp’
MyData(Args&&... args) : i(0), data(std::forward(args)...) {}
~~~~~~~~~~~~^~~~~~
In file included from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/stl_pair.h:59,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/utility:70,
from test_forward.cpp:1:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/move.h:85:5: note: candidate: ‘template<class _Tp> constexpr _Tp&& std::forward(typename std::remove_reference<_Tp>::type&&)’
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
^~~~~~~
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/move.h:85:5: note: template argument deduction/substitution failed:
test_forward.cpp:27:51: note: couldn't deduce template parameter ‘_Tp’
MyData(Args&&... args) : i(0), data(std::forward(args)...) {}
~~~~~~~~~~~~^~~~~~
[hchan@heilinux cpp]$ g++ -Wall test_forward.cpp -o test_forward -O3 -std=c++17
[hchan@heilinux cpp]$
[hchan@heilinux cpp]$
[hchan@heilinux cpp]$
[hchan@heilinux cpp]$ g++ -Wall test_forward.cpp -o test_forward -O3 -std=c++17
test_forward.cpp: In instantiation of ‘void Layer1<Data, Args>::foo(Args&& ...) [with Data = Data; Args = {unsigned char, double, unsigned int}]’:
test_forward.cpp:23:22: required from here
test_forward.cpp:17:20: error: no matching function for call to ‘forward(unsigned char&)’
Data(std::forward(args)...);
~~~~~~~~~~~~^~~~~~
In file included from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/stl_pair.h:59,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/utility:70,
from test_forward.cpp:1:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/move.h:74:5: note: candidate: ‘template<class _Tp> constexpr _Tp&& std::forward(typename std::remove_reference<_Tp>::type&)’
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
^~~~~~~
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/move.h:74:5: note: template argument deduction/substitution failed:
test_forward.cpp:17:20: note: couldn't deduce template parameter ‘_Tp’
Data(std::forward(args)...);
~~~~~~~~~~~~^~~~~~
In file included from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/stl_pair.h:59,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/utility:70,
from test_forward.cpp:1:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/move.h:85:5: note: candidate: ‘template<class _Tp> constexpr _Tp&& std::forward(typename std::remove_reference<_Tp>::type&&)’
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
^~~~~~~
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/move.h:85:5: note: template argument deduction/substitution failed:
test_forward.cpp:17:20: note: couldn't deduce template parameter ‘_Tp’
Data(std::forward(args)...);
~~~~~~~~~~~~^~~~~~
由于某种原因,模板推论似乎失败了。如果我将Data(std::forward(args)...)
更改为Data(std::forward<Args>(args)...)
,它将起作用。
我想知道为什么编译器无法推断出参数类型,以及编译器实际上在想哪种类型(即no matching function for call to ‘forward(unsigned char&)’
)。
基本上,我正在尝试理解为什么需要更多提示(即明确指出<Args>
)。
谢谢!