【问题标题】:Nested call of variadic methods with an additional non-type template parameter of class templates [duplicate]带有类模板的附加非类型模板参数的可变参数方法的嵌套调用[重复]
【发布时间】:2020-01-12 13:25:50
【问题描述】:

使用类模板的附加非类型模板参数(具有默认值)的可变参数方法的嵌套调用会导致 clang 和 g++ 的编译器错误 (msvc 编译没有问题) 如果非-type 被调用方法的模板参数是显式指定的。可以使用以下最小示例重现错误:

#include <iostream>
#include <vector>

template< typename T >
struct S;

template< typename T >
struct SProxy
{
  template< int i = 20, typename... Ts >
  auto f( Ts&&... args );

  S< T >* s1;
  int     ii;
};

template< typename T >
struct S
{
  template< int i = 20, typename... Ts >
  auto f( int ii, Ts && ... args )
  {
    auto res = std::pair< int, int >( std::forward< Ts >( args )... );

    res.first  += i + ii;
    res.second += i + ii;

    return res;
  }
};

template< typename T >
template< int i, typename... Ts >
auto SProxy< T >::f( Ts&&... args )
{
  return s1->f< i >( ii, std::forward< Ts >( args )... );
}

int main( const int argc, const char* argv[] )
{
  S< int >      s;
  SProxy< int > sProxy{ &s, 3 };

  auto pair = sProxy.f< 10 >( 11, 12 );

  std::cout << pair.first << " " << pair.second << std::endl;

  return 0;
}

clang 9.0.0产生的错误信息是

<source>:36:53: error: expected ')'
return s1->f< i >( ii, std::forward< Ts >( args )... );

如果将return s1-&gt;f&lt; i &gt;( ii, std::forward&lt; Ts &gt;( args )... ); 行更改为return s1-&gt;f( ii, std::forward&lt; Ts &gt;( args )... );,即使用默认的非类型模板参数,则代码编译(以及相应的二进制工作)对于clang 和g++ 来说都很好。

我的问题是,最小示例中使用的构造是否不符合 C++17 标准,如果是,为什么,或者使用的语法是否有任何问题,如果是,如何正确执行,或者 (不太可能)如果错误是由 clang 和 g++ 中的错误引起的?


编辑:删除了错误的编译器资源管理器链接

【问题讨论】:

    标签: c++ compiler-errors c++17 variadic-functions class-template


    【解决方案1】:

    首先

    如何正确做[?]

    答案:加一个“template

    // ........VVVVVVVVV   template added
    return s1->template f< i >( ii, std::forward< Ts >( args )... );
    

    使用的语法有什么问题[?]

    是:编译器将第一个 &lt; 解释为关系运算符

    // .........V  seen as relational operator ( s1->f less than i )
    return s1->f< i >( ii, std::forward< Ts >( args )... );
    

    因此您必须指示编译器将以下&lt; 视为模板参数列表的开始。所以添加了“template”。

    题外话:从你的godbolt链接我看到一个完全不同的代码有一个完全不同的问题(与constexpr有关)。

    【讨论】:

      猜你喜欢
      • 2021-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多