首页 > 解决方案 > 依赖基类中的常量使离线定义不匹配?

问题描述

template<template<typename, size_t>class V, typename, size_t N>
struct X{
    static constexpr size_t stride = N;
};

template<typename Num, size_t N>
struct Y;
template<typename Num>
struct Y<Num, 3> : protected X<Y, Num, 3>{
    using X<Y, Num, 3>::stride;

    Y<Num, stride> foo(Num angle, Y<Num, stride> axis) const;
};

我尝试为foo类似提供一个定义:

1.

template<typename Num>
Y<Num, 3> Y<Num, 3>::foo(Num angle, Y<Num, 3> axis) const{};
template<typename Num>
Y<Num, Y<Num, 3>::stride> Y<Num, 3>::foo(Num angle, Y<Num, Y<Num, 3>::stride> axis) const{};
template<typename Num>
Y<Num, X<Y, Num, 3>::stride> Y<Num, 3>::foo(Num angle, Y<Num, X<Y, Num, 3>::stride> axis) const{};

但它们都不被编译器(clang、msvc 和 gcc 7.5-)接受。(为什么 gcc 8.1+ 有效?)

但如果我定义strideYlike static constexpr size_t stride = X<Y, Num, 3>::stride12工作。

或者如果X不是类模板,它们也可以工作。

什么原因?标准声明的错误还是编译器错误?以及如何在这种using X::stride情况下工作?

代码:https ://godbolt.org/z/asn8rj 。

标签: c++c++11templateslanguage-lawyercrtp

解决方案


不祥的是,这是CWG2,标准中缺乏规范,其提交日期已被遗忘。也就是说,您的选项#2 显然是正确的选择,因为它命名了与类中的声明相同的using 声明


推荐阅读