3

I decided to write a stupid code that doesn't work:

template <class T, class Container>
class reversible_stack : protected std::stack<T, Container>
{
public:
    void reverse()
    {
        std::reverse(std::begin(c), std::end(c));
    }
};

this->c is needed instead of c.

Yet there isn't any this needed here:

namespace a
{
    class base
    {
        protected:
            int i;
    };
};

class derived : protected a::base
{
public:
    void foo() { i; }
};

__attribute__ ((__visibility__ ("default"))) makes no difference.

You can see libstdc++ code here. What is the difference that makes this required?

EDIT: This is not a duplicate. See the following code:

namespace standard
{
    template <typename T>
    class container
    {
        protected:
            int i;
    };

    template <typename T, typename Container = container<T>>
    class base
    {
        protected:
            Container c;
    };
}

class derived : protected standard::base<int>
{
public:
    void foo() { c; }
};

Notice how base doesn't need to inherit from container, just like stack doesn't need to inherit from deque (container). Yet this compiles.

Somebody is going to say "it's an implementation detail", but the variable name c is specified by the standard [23.2.3.1].

  • So, according to you, the first code doesn't compile? – CinCout May 05 '16 at 11:11
  • @jotik It's a protected member of `std::stack` of type container. – uh oh somebody needs a pupper May 05 '16 at 11:13
  • _"name c is specified by the standard [23.2.3.1]"_?! – zdf May 05 '16 at 11:13
  • @CinCout [Try it yourself](http://coliru.stacked-crooked.com/a/741564662b8d4a88) – uh oh somebody needs a pupper May 05 '16 at 11:13
  • @ZDF According to the [libstdc++](https://gcc.gnu.org/onlinedocs/gcc-5.3.0/libstdc++/api/a01278_source.html) comment. Without a document number, it's not really easy to look it up because section numbers change. In 23.6.3.1 of N4140: `Container c;` – uh oh somebody needs a pupper May 05 '16 at 11:14
  • Since it gives rise to a class from a definition of a definition based on a definition of a definition, give the compiler a break and throw it a bone here! – Mike May 05 '16 at 11:18
  • It's because templates! – Lightness Races in Orbit May 05 '16 at 11:18
  • If you think that this is a valid statement, you should provide a link. – zdf May 05 '16 at 11:19
  • It's late so I can't set it up but it would be an interesting experiment to see if it notices that this->something_thats_not_there is flagged as an error or not before the template is used. – Mike May 05 '16 at 11:23
  • 1
    @user6292850: _"EDIT: This is not a duplicate"_ Yes, it is. Your example code does not adequately match the failing testcase. See this: http://coliru.stacked-crooked.com/a/663c739b816adfcf A base `standard::base` is not the same as a base `standard::base`. That is, your failing testcase has base `std::stack`, not base `std::stack`. That's the difference. – Lightness Races in Orbit May 05 '16 at 11:24
  • You always use this-> when messing around with templates. Compilers work differently in both cases.To be specific the Type checking is devided into two parts in the template case...before and after the template parameter is known while in the second case it's done all at once. – Ilan Kutsman May 05 '16 at 11:35
  • (or "not base `std::stack>`", I should say) – Lightness Races in Orbit May 05 '16 at 11:36

0 Answers0