具有可变参数模板构造函数的演绎指南和可变参数类模板 - 不匹配的参数包长度

Vit*_*meo 8 c++ template-argument-deduction c++17

请考虑以下class定义和演绎指南:

template <typename... Ts>
struct foo : Ts...
{
    template <typename... Us>
    foo(Us&&... us) : Ts{us}... { }
};

template <typename... Us>
foo(Us&&... us) -> foo<Us...>;
Run Code Online (Sandbox Code Playgroud)

如果我尝试foo使用显式模板参数进行实例化,则代码可以正确编译:

foo<bar> a{bar{}}; // ok
Run Code Online (Sandbox Code Playgroud)

如果我尝试foo通过演绎指南实例化...

foo b{bar{}};
Run Code Online (Sandbox Code Playgroud)
  • g ++ 7产生编译器错误:

    prog.cc: In instantiation of 'foo<Ts>::foo(Us ...) [with Us = {bar}; Ts = {}]':
    prog.cc:15:16:   required from here
    prog.cc:5:27: error: mismatched argument pack lengths while expanding 'Ts'
         foo(Us... us) : Ts{us}... { }
                               ^~~
    
    Run Code Online (Sandbox Code Playgroud)
  • clang ++ 5爆炸:

    #0 0x0000000001944af4 PrintStackTraceSignalHandler(void*) (/opt/wandbox/clang-head/bin/clang-5.0+0x1944af4)
    #1 0x0000000001944dc6 SignalHandler(int) (/opt/wandbox/clang-head/bin/clang-5.0+0x1944dc6)
    #2 0x00007fafb639a390 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11390)
    #3 0x0000000003015b30 clang::Decl::setDeclContext(clang::DeclContext*) (/opt/wandbox/clang-head/bin/clang-5.0+0x3015b30)
    ...
    clang-5.0: error: unable to execute command: Segmentation fault
    
    Run Code Online (Sandbox Code Playgroud)

wandbox上的实例

虽然clang ++肯定是错误的(报告为问题#32673),但g ++在拒绝我的代码时是否正确?我的代码格式不正确吗?

Jac*_*kie 7

为了进一步简化您的示例,GCC似乎没有在演绎指南中实现可变参数模板参数:

https://wandbox.org/permlink/4YsacnW9wYcoceDH

我没有在标准或cppreference.com上的演绎指南的措辞中看到任何关于可变参数模板的明确提及.我看不到不允许这种标准的解释.因此我认为这是一个错误.

  • 考虑到`std :: tuple`有演绎指南,我想假设允许可变参数模板是非常安全的. (2认同)