Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

Sepplesfags, help!

Name: Anonymous 2008-12-08 18:34


template <class T>
class A
{
public:
    typedef T Foo;
};

template <class T>
class B
{
    A<T>::Foo foo;
};

int main()
{
    B<int> b;
    return 0;
}



test.cpp:11: error: type ‘A<T>’ is not derived from type ‘B<T>’
test.cpp:11: error: expected ‘;’ before ‘foo’


What the FUCK?

Name: Anonymous 2008-12-08 18:44

typename

Name: Anonymous 2008-12-08 18:44

What the SEPPLES?
Fixed

Name: Anonymous 2008-12-08 18:53

typename A<T>::Foo foo;

Name: 4 2008-12-08 18:54

Name: Anonymous 2008-12-08 19:03

c++ templates lol

Name: Anonymous 2008-12-08 20:07

>>6
lol looks like a man holding his arms up in the air, in jubilant celebration.

Name: Anonymous 2008-12-08 20:13

>>7
As if he conjured the spirits with his spells

Name: Anonymous 2008-12-08 20:27

Thanks for the help. Now for the next WTF:


class A
{
protected:
    void Foo() const {}
};

class B : public A
{
public:
    void Bar(const A& a)
    {
        a.Foo();
    }
};


test.cpp: In member function ‘void B::Bar(const A&)’:
test.cpp:4: error: ‘void A::Foo() const’ is protected
test.cpp:12: error: within this context


I thought the whole point of protected was so that inherited classes could use certain member variables/functions, but keep them off-limits from others.

Name: Anonymous 2008-12-08 20:39

That's exactly what it's doing.

Name: Anonymous 2008-12-08 20:54

>>10
I'd argue that what that's not what it's doing. Say we have this simple class.


class A
{
    void Foo() const {}
public:
    void Bar(const A& a)
    {
        a.Foo();
    }
};


That's legal, as it ought to be--an A object can send a private message to any other A object. In my example >>9, why shouldn't a B object be able to send a protected message to any other A object, since a B is an A?

Name: Anonymous 2008-12-08 21:56

>>11
Perhaps because it might not be the same exact kind of A that the other A is. Either way, you're using Sepples now, just give in and stop expecting things to make sense.

Name: Anonymous 2008-12-09 5:08

>>12
So the "is a" relation is completely broken in Sepples? Figures.

Name: Anonymous 2008-12-09 8:05

>>13
Java behaves the same way, so it can't be broken.

Name: Anonymous 2008-12-09 8:07

What the fuck is the difference between template <class T> and template <typename T>. If there is no difference, WHY SUPPORT BOTH FOR FUCK'S SHIT?. Backwards compatibility is not good enough an answer.

typename A<T>::Foo foo;
PIG DISGUSTING. A<T>::Foo is already a god damn class. What does the compiler need the typename for?

Name: Anonymous 2008-12-09 10:46

>>9
Learn the difference between the different types of inheritance in Sepples.

Name: Anonymous 2008-12-09 10:48

>>15
Sepples has a badly defined, ambiguous grammar. That's why.

Name: Anonymous 2008-12-09 11:02

NEVER FORGET THE HEROES THAT GAVE THEIR TIME AND THEIR LIVES TO DIE FOR THE GREATER CAUSE OF MAKING THE PLEASURE OF BEING CUMMED INSIDE A GOOGLE MEME. YOUR SACRIFICE WILL NOT BE FORGOTTEN.

NVR FGT

Name: Anonymous 2008-12-09 13:54

>>15
Stolen from: Thinking in C++, vol.2, Ch.6, The typename keyword
Consider the following:

    //: C06:TypenamedID.cpp
    // Using 'typename' to say it's a type,
    // and not something other than a type
    //{L} ../TestSuite/Test

    template<class T> class X {
      // Without typename, you should get an error:
      typename T::id i;
    public:
      void f() { i.g(); }
    };

    class Y {
    public:
      class id {
      public:
        void g() {}
      };
    };

    int main() {
      Y y;
      X<Y> xy;
      xy.f();
    } ///:~


The template definition assumes that the class T that you hand it must have a nested identifier of some kind called  id. But id could be a member object of  T, in which case you can perform operations on id directly, but you couldn’t “create an object” of “the type  [code]id.” However, that’s exactly what is happening here: the identifier id is being treated as if it were actually a nested type inside T. In the case of class  Yid is in fact a nested type, but (without the  typename keyword) the compiler can’t know that when it’s compiling  X.

If, when it sees an identifier in a template, the compiler has the option of treating that identifier as a type or as something other than a type, then it will assume that the identifier refers to something other than a type. That is, it will assume that the identifier refers to an object (including variables of primitive types), an enumeration or something similar. However, it will not – cannot – just assume that it is a type. Thus, the compiler gets confused when we pretend it’s a type.

The typename keyword tells the compiler to interpret a particular name as a type. It must be used for a name that:

   1. Is a qualified name, one that is nested within another type.
   2. Depends on a template argument. That is, a template argument is somehow involved in the name. The template argument causes the ambiguity when the compiler makes the simplest assumption: that the name refers to something other than a type.

Because the default behavior of the compiler is to assume that a name that fits the above two points is not a type, you must use typename even in places where you think that the compiler ought to be able to figure out the right way to interpret the name on its own. In the above example, when the compiler sees T::id, it knows (because of the typename keyword) that id refers to a nested type and thus it can create an object of that type.

The short version of the rule is: if your type is a qualified name that involves a template argument, you must use typename.

Name: Anonymous 2008-12-09 14:02

>>19
I ask, why is typename required by Sepples in that context", you answer
typename is required
Gee, thanks anyway. I mean, for fucking shit's sake, what could T::id stand for, if not a type? The trailing i make is pretty god damn unambiguous.

Name: Anonymous 2008-12-09 14:07

>>20
Bad reading comprehension? READ THE FUCKING TEXT AGAIN!

Name: Anonymous 2008-12-09 14:14

>>21
oops it was truncated, BRB

Name: Anonymous 2008-12-09 14:24

>>21
All right I've read it. I still think T::id i is unambiguous, typename is there just to make compiler design easier. Those FUCKING slackers.

Name: Anonymous 2008-12-09 14:34

>>23
Write a better one then. It's not rocket science, right?

Name: Anonymous 2008-12-09 14:43

>>24
I would, but it wouldn't adhere to the standard. It's Sepples' failure, not the compiler's failure. Of course, if you can come up with a context where the meaning of T::id is ambiguous, you will be an triumphant of INTERNETS, and this thread in particular.

Name: Anonymous 2008-12-09 15:21

Name: Anonymous 2008-12-09 15:27

#include <iostream>

using namespace std;

template <class T>
class A {
public:
    void f() {
        cout << "lol sepples" << endl;
    }
};

template <class T>
class B : public A<T> {
public:
    void g() {
        f();
    }
};

int main() {
    B<int> b;
    b.g();
}[code]

[code]sepples.cpp: In member function ‘void B<T>::g()’:
sepples.cpp:17: error: there are no arguments to ‘f’ that depend on a template parameter, so a declaration of ‘f’ must be available

Name: Anonymous 2008-12-09 15:30

>>26
Well I guess the context insensitive typename solution sure repairs Sepples' already FUBAR grammar. All right, you win. Congratulations.

Name: Anonymous 2008-12-09 15:33

>>27
Please, stop posting this shit. It's making me sad.

Name: Anonymous 2008-12-09 15:52

Apologies in advance, >>29.

>>27
This error actually caused me a great deal of annoyance. It worked in one compiler, but not another. I switched to:

template<class T>
struct Templategasm {
  struct A { void f() { } };
  struct B : A { void g() { f(); } };
};

int main() {
  Templategasm<int>::B b;
  b.g();
}


rather than explicitly qualifying names everywhere (it's still needed in some places, but it's generally more readable). It works because A becomes a non-dependent base class in Sepplespeak, and is thus checked when looking for non-dependent names. Talk about PIG DISGUSTING.

Name: Anonymous 2008-12-09 15:59

>>30
Hi, Lee!

Name: Anonymous 2008-12-09 16:34

>>30
I prefer a typedef, like STL.

template<class T>
struct Templategasm {
  struct A { void f() { } };
};
int main() {
  typedef Templategasm<int>::A A_int
  A_int a;
  a.g();
}

Still pig disgusting but it's more readable and doesn't depend on the compiler optimization too much.

#include "prog.h"

using namespace std;

template<class A, class R>
struct Hax :
  unary_function<A, R>
{
  typedef R result_t;
  typedef A argument_t;
 
  result_t
  operator()(const argument_t& a)
  const
  {
    // TODO Hax
    return result_t(a.anus);
  }
};

struct Anus
{
}

struct Poster
{
  Anus anus;
};

struct HaxxedAnus
{
  HaxxedAnus(Anus& a)
  {
    /* The pleasure of being cummed inside */
  }
};

int main()
{
  typedef Hax<Poster, HaxxedAnus> HaxP_t;
  HaxP_t stepanov;
  deque<HaxP_t::result_t> haxxed_anii;
  transform(istream_iterator<HaxP_t::argument_t>(ThreadStream("Sepplesfags, help!")),
            istream_iterator(),
            back_inserter(haxxed_anii),
            stepanov);
  return 0;
}

Name: Anonymous 2008-12-09 17:15

The readability of modern Sepples is rapidly approaching Perl.

Name: Anonymous 2008-12-09 17:29

>>33
Just wait for Sepplesox. That will clean up the grammar.

Name: Anonymous 2008-12-09 21:58

>>34
More like Seppleslox, am i right?

Name: Anonymous 2008-12-09 22:01

No, wait... How do you pronounce Seppleslx?

Name: Anonymous 2008-12-10 0:54

>>11
Inheritance does not mean access.  When you derived B from A you inherited the Foo function, so every B has its own Foo to call.  This does not mean that nonlocal A's have to give access to their protected methods in B methods now.

Whereas your other example has nothing to do with this at all. Foo is used within one of the other class methods. Nothing wrong with that.

Name: Anonymous 2008-12-10 1:19

>>37
I get how it works now, but I guess that protected wasn't explained well to me before. I think some sort of access level like I want should exist--like protected, but lets derived classes call the methods/use the variables of objects of the base class.

Name: Anonymous 2008-12-10 2:19

>>35
No.  It's C++0x, actually.

Name: Anonymous 2008-12-10 9:52

>>39
So cocks basically

Name: Anonymous 2008-12-10 9:54

cocks

Name: Anonymous 2008-12-10 11:05

Sepplecocks

Name: Anonymous 2008-12-10 11:10

cockles and mussels

Name: Anonymous 2008-12-10 11:15

"COx" like Alan Cox. Coincidence?

Name: Anonymous 2008-12-10 11:41

Anonymous (2008). Sepples Considered Harmful. 4chan Journal of /prog/ramming, Internets.

Name: Anonymous 2009-11-30 1:05

>>25
I have ruminated for a while before posting, and I have decided that the following is ambiguous without typename:

T::id();

Is that constructing a temporary value of type T::id, or calling a static member function T::id? Bear in mind that the compiler doesn't know what T is at this point, so it can't just look at T and decide.

Name: Anonymous 2009-11-30 2:39

>>46
A compiler could still resolve that at instantiation time.  The only problem is that some constructions would force it to generate several alternative parse trees, making sepples compilation even slower.

Name: Anonymous 2009-11-30 2:49

>>23
To be fair, it's only pig shit GCC that bitches about this. MSVC is actually sane about parsing it. I had uhh... let me remember.

for (vector<T>::iterator iter = vec.begin(); iter != vec.end(); ++iter)

MSVC took it like a champ and then GCC whined like the little shitty schoolgirl bitch that it is.

The solution was not vector<typename T> as you might expect, either. It was typename vector<T>. I should be angry at the standard, but seriously, this should BE the standard.

Name: Anonymous 2009-11-30 2:55

>>46
The compiler should complain in the event that it cannot effectively choose. It shouldn't complain in instances where it can (the majority).

Name: Anonymous 2009-11-30 2:58

>>48
It's not vector<typename T> because we’re not telling the compiler that T is a type; we are hinting to the compiler that vector<T>::iterator is a type.

Name: Anonymous 2009-11-30 2:59

>>48
The solution was not vector<typename T> as you might expect, either. It was typename vector<T>. I should be angry at the standard, but seriously, this should BE the standard.
Why would you expect that?  Of course T is a type, you just declared it that way.  But vector<T>::iterator could be anything, so you need to clarify it.

Name: Anonymous 2009-11-30 3:05

Even better, mixing the template keyword in:

typedef typename _Alloc::template rebind<_List_node<_Tp> >::other _Node_alloc_type;

Name: Anonymous 2009-11-30 4:15

>>51
That's why MSVC has a perfect resolution of my intent. Because I need to clarify it.

Name: Anonymous 2010-12-10 0:37

Name: Anonymous 2010-12-17 1:39

FOLLOW THE NEW GNAA TWITTER AT http://twitter.com/Gary_Niger

Don't change these.
Name: Email:
Entire Thread Thread List