代码之家  ›  专栏  ›  技术社区  ›  helloworld922

在调用时仅指定一些模板参数

  •  0
  • helloworld922  · 技术社区  · 5 年前

    考虑一小段可变模板代码:

    #include <type_traits>
    
    template<int Dim, class... Idcs>
    std::enable_if_t<sizeof...(Idcs) == 1> doit(Idcs... idcs)
    {}
    
    int main()
    {
        doit<0>(1);
    }
    

    当我使用gcc/clang编译它时,它编译得很好,并且 Idcs 推断为 (int) .

    但是,当我尝试使用英特尔的编译器(版本18.0.0,20170811)编译时,出于某种原因,它认为我是在手动指定 入侵检测系统 作为空参数包,然后 enable_if_t 失败。

    来自ICC的编译器错误:

    myfile.cpp(9): error: no instance of function template "doit" matches the argument list
                argument types are: (int)
        doit<0>(1);
        ^
    myfile.cpp(4): note: this candidate was rejected because there is a type mismatch after argument substitution
      std::enable_if_t<sizeof...(Idcs) == 1> doit(Idcs... idcs)
                                             ^
    
    compilation aborted for myfile.cpp (code 2)
    
    

    这可以通过更改 main() 完全指定所有模板参数

    doit<0, int>(1);
    

    但是,我想理解为什么原始代码在所有C++ 14编译器上都不会给出相同的结果。这是期望编译成功/失败的东西,还是这是某种未定义的行为,为什么?

    作为参考,这些是我用来编译的命令(在Linux上,各种版本/风格):

    g++ -std=c++14 myfile.cpp
    clang++ -std=c++14 myfile.cpp
    icc -std=c++14 myfile.cpp
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   bolov    5 年前

    这很可能是ICC中V19中修复的错误: https://godbolt.org/z/k1vbY9

    更多的调查显示ICC v18(不编译代码)可以正确推导 Idcs 没有 enable_if : https://godbolt.org/z/WCZ_w8

    template<size_t Dim, class... Idcs>
    size_t doit(Idcs... idcs)
    {
        static_assert(sizeof...(Idcs) == 1);
        return sizeof... (Idcs);
    }
    
    auto test()
    {
        return doit<0>(1); // correctly returns 1 even on icc v18
    }