【问题标题】:Bug in gcc with const& template parameters?带有 const& 模板参数的 gcc 中的错误?
【发布时间】:2017-02-09 09:43:56
【问题描述】:

考虑this代码:

#include <type_traits>

template < int > struct II { };
template < const int& > struct RR { };

template < template <auto> typename Class, typename Type > struct Check : std::false_type { };
template < template <auto> typename Class, auto NonTypes > struct Check<Class,Class<NonTypes>> : std::true_type { };

constexpr int TEN = 10;
constexpr const int& REF = TEN;

static_assert(Check<II,II<TEN>>::value); // passes
static_assert(Check<RR,RR<REF>>::value); // FAILS!?

我使用的是 gcc-7.0.1,here 是一个活生生的例子。问题是这是编译器错误还是我做错了什么?

【问题讨论】:

  • 只是我的猜测:普通的auto(来自NonTypes)无法推断出与const int&amp;Class 下推断的内容相匹配的引用类型(至少它适用于@ 987654328@)
  • @PiotrSkotnicki 与decltype(auto) 一起工作难道不是很有意义吗?
  • @user975989 我认为匹配模板特化归结为推导发明的函数模板的类型,其中decltype(auto) 没有用

标签: c++ templates c++17 auto non-type


【解决方案1】:

让我们稍微简化一下例子:

template <template <auto> class C, auto N>
void foo(C<N> ) { }

int main() {
    foo(II<TEN>{} ); // ok
    foo(RR<REF>{} ); // error
}

问题是正常的auto 推导规则适用于N,它在REF 的情况下被推导为输入int。非类型模板参数类型 - int const&amp; - 和参数 - int 之间存在不匹配,因此它的格式不正确。

如果我们将示例翻转为采用auto const&amp; N(或auto&amp;&amp; N),那么由于同样的原因,II&lt;TEN&gt; 调用的格式错误 - 我们现在会得到一个模板参数引用类型,但参数是非引用类型。

今天,您无法使用该语言中的一个函数来处理这两种情况。你需要两个:

template <template <auto> class C, auto N>     void foo(C<N> ) { } // #1
template <template <auto&&> class C, auto&& N> void foo(C<N> ) { } // #2

int main() {
    foo(II<TEN>{} ); // ok: calls #1
    foo(RR<REF>{} ); // ok: calls #2
}

与您的原始示例类似:您需要一种专门化的值和一种专门化的引用。 C 的模板模板非类型参数中的引用可能不是必需的。

【讨论】:

    猜你喜欢
    • 2011-08-25
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 2017-08-28
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    相关资源
    最近更新 更多