Рекурсивный, включая файлы шаблонов, не компилируется - PullRequest
0 голосов
/ 15 февраля 2020

Я пытаюсь использовать простой шаблонный класс для декодирования разных типов. Я получаю эту ошибку

Decoder.h:16: error: non-const lvalue reference to type 'CheckDecoder::NormalType' cannot bind to a value of unrelated type 'CheckDecoder::NestedType'
        CheckDecoder::decode(m_value, istr);
                             ^~~~~~~

На самом деле это часть большого проекта, но я делюсь простым проектом, чтобы показать эту конкретную c проблему. Пожалуйста, помогите решить эту проблему, а также предоставьте некоторые ссылки, чтобы узнать больше об этой проблеме с шаблоном.

Это четыре файла в проекте

main. cpp

#include <iostream>
#include <NormalType.h>
#include <NestedType.h>
#include <Decoder.h>

using namespace std;
using namespace CheckDecoder;
int main()
{
    Decoder<NormalType> d_normal;
    d_normal.decode(std::cin);

    Decoder<NestedType> d_nested;
    d_nested.decode(std::cin);
    return 0;
}

Decoder.h

#ifndef DECODER_H
#define DECODER_H

#include <iostream>

namespace CheckDecoder {


template<typename T>
class Decoder
{
public:
    void decode(std::istream& istr)
    {
        // some complex code
        CheckDecoder::decode(m_value, istr);
    }

    T m_value;
};

}
#endif // DECODER_H

NormalType.h

#ifndef NORMALTYPE_H
#define NORMALTYPE_H

#include <iostream>

namespace CheckDecoder {

class NormalType
{

};

void decode(NormalType& t, std::istream& istr)
{
    // do something
}
}
#endif // NORMALTYPE_H

NestedType.h

#ifndef NESTEDTYPE_H
#define NESTEDTYPE_H

#include <Decoder.h>

namespace CheckDecoder {

class NestedType
{

private:
    Decoder<int> m_value;
};

void decode(NestedType& t, std::istream& istr)
{
    // do something
}
}

#endif // NESTEDTYPE_H

1 Ответ

1 голос
/ 15 февраля 2020

Способ заказа включений: сначала main.cpp объявляется CheckDecoder::decode(NormalType), затем CheckDecoder::decode используется Decoder и, наконец, CheckDecoder::decode(NestedType) объявляется. В точке определения в Decoder видна только первая декларация; второй не участвует в разрешении перегрузки. Его можно было найти с помощью поиска, зависящего от аргумента, но способ его вызова - с определенным именем - подавляет это.

Один из возможных обходных путей - переместить вызов в область, где другие вещи с именем decode не мешайте, а затем используйте безусловное имя, чтобы позволить зависящему от аргументов поиску выполнить свою задачу. Примерно так:

struct DecoderHelper {
  template <typename T>
  static void DoDecode(T& value, std::istream& istr) {
    decode(value, istr);
  }
};

template<typename T>
class Decoder
{
public:
    void decode(std::istream& istr)
    {
        // some complex code
        DecoderHelper::DoDecode<T>(m_value, istr);
    }

    T m_value;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...