a constant in dependent base class make out-of-line definition not matched?
Asked Answered
W

1

4
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;
};

I try to provide a definition for foo like:

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{};

but none of them is accepted by compilers (clang, msvc, and gcc 7.5-). (why gcc 8.1+ works?)

but if I define stride at Y like static constexpr size_t stride = X<Y, Num, 3>::stride, 1 and 2 work.

or if X is not a class template, they work as well.

what's the reason? a mistake declared by standard or just a compiler bug? and how to work at the using X::stride situation?

code: https://godbolt.org/z/asn8rj.

Wawro answered 20/10, 2020 at 10:27 Comment(4)
I'm not gonna interfere with your pursuit of a normative answer, but I would point out that it's fairly easy to work around the problem. Adding an alias using foo_res = Y<Num, stride>; and providing the out of line definition as auto Y<Num, 3>::foo(Num, Y::foo_res) const -> Y::foo_res {} appeases all the compilers.Contrarily
@StoryTeller-UnslanderMonica oh, it's a good idea. just using A3<T> = Y<T, 3> will solve it. I think it's equivalent to redefining something to make them to be the same stride. anyway, thanks for help.Wawro
Remember that template (X) could be specialized, so option 1 is clearly wrong.Chamber
Option 2/3 seems more promising, butstride is not directly from Y or from X (remember that X might be specialized and we are in partial specialization). I try trailing return type as option 4 but clang still dislike it :/.Chamber
B
3

This is, ominously, CWG2, a lack of specification in the standard whose filing date has literally been forgotten. That said, your option #2 seems clearly the correct choice, since it names the same using-declaration as the declaration in the class.

Bygone answered 21/10, 2020 at 3:59 Comment(1)
the match rule is even unspecified? amazing.Wawro

© 2022 - 2024 — McMap. All rights reserved.