Typedef template error

Can someone explain why this code gives an error:

error C2039: 'RT' : is not a member of 'ConcreteTable'

(at least when compiled with VS2008 SP1)

class  Record
{
};

template <class T>
class Table
{
public:
    typedef typename T::RT Zot; // << error occurs here
};

class ConcreteTable : public Table<ConcreteTable>
{
public:
    typedef Record RT;
};

What can be done to fix this. Thanks!

Update: Thank you for noting this problem and for all the suggestions. This fragment was based on code that provided an extension point in the existing code base, and the main goal of the project was to reduce the amount of work (input) needed to add new extensions using this mechanism.

A separate style class of type type is really better suited for the solution. Especially since I could even wrap it in a C-style macro. If the style police aren't looking!

+3
source share
7

, ConcreteTable , T:: RT. , ++ ( , undefined), , ( , , , ) - const bool, false, ).

typedefs, , , RT ,

template <class T, class RT>
class Table
{
public:
    typedef typename RT Zot;
};

class ConcreteTable : public Table<ConcreteTable, Record>
{
public:
    typedef Record RT;
};

, RT Table<>::Zot,

template <class T>
class Table
{
public:
  struct S {
    typedef typename RT Zot;
  };
};

class ConcreteTable : public Table<ConcreteTable>
{
public:
    typedef Record RT;
};

struct

template <class T>
struct TableTraits<T>;

template <class T>
struct TableTraits<Table<T> > {
  typedef typename T::RT Zot;
};

, / , , .

void f(typename T::RT*); // this won't work

template <class U>
void f(U*); // this will

T:: RT , , ConcreteTable .

+4

CponcreateTable , .

:

class  Record
{
};


template <class T>  Table
{
public:
    typedef typename T::RT Zot; // << error occurs here
};


class ConcreteTableParent
{
public:
    typedef Record RT;
};


 class ConcreteTable: public Table<ConcreteTableParent>
{
public:
...
};
+1

- ?

class  Record
{
};

template <class T>
class Table
{
public:
    typedef typename T Zot;
};

class ConcreteTable : public Table<Record>
{
public:
    typedef Record RT;  //You may not even need this line any more
};
+1

, ConcreteTable , ConcreteTable, .

, , . , , , ConcreteTable, , . , ConcreteTable - :

class Record {};

template <class T>
class Table {
public:
    typedef T RT;
};

class ConcreteTable : public Table<Record> {
};

, - .

+1

, , . , :

template <class T>
class Table
{
public:
    typedef typename T::RT Zot; 
};

class ConcreteTable : public Table<ConcreteTable>
{
public:
    typedef Zot RT;
};

-.

, , , ; ( ConcreteTable) RT, RT .

, , .

+1

Table<ConcreteTable> , ConcreteTable - . , CRTP, , :

class  Record
{
};

template <class T, class U>
struct Table
{
    typedef U RT;
};

struct ConcreteTable : Table<ConcreteTable, Record>
{
};

, ConcreteTable - Table, , . , :

struct  Record
{
};

template <class T>
struct Table
{
    void foo()
    {
      typedef typename T::RT Zot;
      Zot a; // ...
    }
};

struct ConcreteTable : Table<ConcreteTable>
{
    typedef Record RT;
};

int main()
{
    ConcreteTable tab;
    tab.foo();
}
+1

, , , , "", , . (RT) , ConcreteTable. - std:: iterator, :

template <class Category, class T, class Distance = ptrdiff_t,
      class Pointer = T*, class Reference = T&>
  struct iterator {
    typedef T         value_type;
    typedef Distance  difference_type;
    typedef Pointer   pointer;
    typedef Reference reference;
    typedef Category  iterator_category;
  };

, :

struct ExampleIterator : std::iterator<std::forward_iterator_tag, Example>

This is exactly what you want to do. Note that the RecordType fields are indeed in the superclass and passed through the template parameters. This is the best way to do this, it is in the standard library because of this.

If you want to do more specialization of the ConcreteTable subclass, you can always override the methods from the table as well as use the template options.

+1
source

Source: https://habr.com/ru/post/1702503/


All Articles