【问题标题】:Specifying only some template parameters at call time在调用时仅指定一些模板参数
【发布时间】:2019-08-14 00:01:01
【问题描述】:

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

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

但是,当我尝试使用 Intel 的编译器(版本 18.0.0,20170811)编译它时,它出于某种原因认为我手动将 Idcs 指定为空参数包,然后 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

【问题讨论】:

  • @bolev 添加,我还将第一个模板参数类型更改为int,因为我不小心包含了一些其他不相关的标头,这些标头定义了size_t

标签: c++ c++14 language-lawyer icc template-argument-deduction


【解决方案1】:

这很可能是 icc 中的一个错误,已在 v19 中修复:https://godbolt.org/z/k1vbY9

更多调查显示 icc v18(它不会编译您的代码)在没有 enable_if 的情况下正确推断出 Idcshttps://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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多