模板推导在std :: forward中失败?

时间:2019-07-23 07:00:59

标签: c++ g++ c++14

#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>)。

谢谢!

0 个答案:

没有答案