9

我发现下面的最小示例适用于 gcc 和 clang 甚至 Visual Studio,但它不能使用 icc 编译。我正在尝试确定这是否是有效的 C++,但我无法找到标准的相关部分来回答我的问题,因为这是几个不同的概念相结合。

// struct with multiple template parameters
template<typename A, typename B = int>
struct C
{

};

// struct that tries to use C's default second parameter without specifying it
template<typename D, template<typename E, typename ...> class F>
struct G
{
  F<D> h;
};

int main()
{
  G<char, C> i;
}

使用 icc (16.0.3),编译会出现以下错误:

struct.cpp(12): error: too few arguments for template template parameter "F"
    F<D> h;

          detected during instantiation of class "G<D, F> [with D=char, F=C]" at line 17

这是有效的 C++ 吗?

对我来说似乎应该是,因为C它的第二个模板参数有一个默认值,这意味着F<D>withF = C应该是一个有效的结构。

4

1 回答 1

4

我相信这是一个 gcc/clang 错误。这与 [仍然开放的] CWG 第 150 期有关。提供的理由包括:

模板模板形参的形参允许使用默认实参,这些默认实参将在模板定义中的模板模板形参的特化中单独考虑;模板模板参数的参数的任何默认参数都将被忽略

模板模板参数F没有任何默认参数 - 并且默认参数C被忽略。因此,正如 ICC 建议的那样,我们最终应该得到一个格式不正确的专业化。

在问题中提供的示例中,gcc 和 clang 似乎都实现了该规则(都不允许调用f()并且都通过operator float()Mark Mitchell 示例中的路径。

于 2016-06-06T14:41:17.813 回答