Как возвратить ПУСТОЙ УКАЗАТЕЛЬ из метода в Шаблонном классе

Для единственного объекта, счетного в Java, это был бы Collections.singleton ("строка");

В c# это будет более эффективным, чем новый Список:

public class SingleEnumerator<T> : IEnumerable<T>
{
    private readonly T m_Value;

    public SingleEnumerator(T value)
    {
        m_Value = value;
    }

    public IEnumerator<T> GetEnumerator()
    {
        yield return m_Value;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        yield return m_Value;
    }
}

, но там более простой способ использовать платформу?

5
задан Aamir 8 September 2009 в 09:09
поделиться

9 ответов

Если вы хотите вернуться по значению и не хотите возиться с возвращаемыми указателями и новыми / удаляемыми, вы можете просто сделать вот так:

template <typename T>
boost::optional<T> Test<T>::FindItem(T item)
{
    if(found)
        //return original value
    else
        return boost::none; 
}

и использовать это так:

Test<int> var;
boost::optional<int> V = var.FindItem(5)

if (V)
{
    // found
    int val = *V;
}
else
{
    // not found
}
14
ответ дан 18 December 2019 в 05:23
поделиться

Большинство типов конструируются по умолчанию, у вас есть шаблон признаков класс, который может быть специализированным (по умолчанию возвращается инициализированный объект по умолчанию).

template <class T>
struct Make {
    static T Default()
    {
         return T();
    }
};


class not_default_constructable {
public:
    explicit not_default_constructable(int i) {}
};

// specialize for not_default_constructable     
template <>
struct Make <not_default_constructable> {
    static not_default_constructable Default()
    {
         return not_default_constructable(42);
    }
};
2
ответ дан 18 December 2019 в 05:23
поделиться

У вас есть функция, которая может возвращать действительный объект, но также указывает на то, что действительного объекта не существует. В сочетании с ситуацией, когда допустимы все возможные значения объекта, это проблема проектирования с вашей функцией поиска. (Даже если вы настроили функцию таким образом, чтобы она, например, возвращала пустую строку, если она ее не находила, как это будет отличаться от успешного поиска пустой строки?)

Со временем появилось несколько способов выхода из ситуации. эта дилемма была обнаружена. Таким образом, вы можете вернуть указатель / итератор вместо фактического значения. Тогда итератор указателя / конца NULL будет указывать «не найден». Или вы можете взять значение по неконстантной ссылке, присвоить ему результат и указать успех / неудачу возвращенным логическим значением. Или возьмите одно из других решений, размещенных здесь. Но все потребует, чтобы вы изменили интерфейс функции, потому что в нем есть ошибка дизайна.

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

7
ответ дан 18 December 2019 в 05:23
поделиться

Здесь Страуструп приводит пару аргументов для исключения NULL в C ++:

  • Определение просто 0 , поэтому фактического усиления нет [и многое другое для ввода]
  • Это макрос, и его лучше избегать в C ++.

Предложение, опять же с той страницы это:

  • Используйте простой 0 или (для C ++ 0xw независимо) nullptr .

Во-вторых, если вы хотите вернуть недействительный указатель как сигнал об ошибке , вам нужно объявить функцию, возвращающую указатель на тип, а не сам тип.

В-третьих, большинство стандартных библиотечных функций find () возвращают итераторы, а не элементы напрямую. Это дает вам возможность реализовать случай «ничего не найдено» по-другому.

  • Используйте простой 0 или (для C ++ 0x независимо) nullptr .

Во-вторых, если вы хотите вернуть неверный указатель в качестве сигнала об ошибке, вы необходимо объявить функцию как возвращающую указатель на тип, а не сам тип.

В-третьих, большинство стандартных библиотечных функций find () возвращают итераторы, а не элементы напрямую. Это дает вам возможность реализовать случай «ничего не найдено» по-другому.

  • Используйте простой 0 или (для C ++ 0x независимо) nullptr .

Во-вторых, если вы хотите вернуть неверный указатель в качестве сигнала об ошибке, вы необходимо объявить функцию, возвращающую указатель на тип, а не сам тип.

В-третьих, большинство стандартных библиотечных функций find () возвращают итераторы, а не элементы напрямую. Это дает вам возможность реализовать случай «ничего не найдено» по-другому.

9
ответ дан 18 December 2019 в 05:23
поделиться

Вы должны вернуть T * non T

2
ответ дан 18 December 2019 в 05:23
поделиться

Возможно, я слишком упрощаюсь, но я предпочитаю просто возвращать логическое значение :

template <typename T>
bool Test<T>::FindItem(T item)
{
    if (!found)
        return false;    
    item = <found item>;        
    return true; 
}
2
ответ дан 18 December 2019 в 05:23
поделиться

Return T () . Если T имеет тип sometype * , он будет инициализирован нулевым указателем. Если T имеет тип sometype , он вернет объект, созданный с помощью конструктора по умолчанию, которого должно хватить ( std :: string будет пустым, целые типы например int s будет 0 и т. д.).

0
ответ дан 18 December 2019 в 05:23
поделиться

Вы можете вызвать исключение, если оно не найдено.

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

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

1
ответ дан 18 December 2019 в 05:23
поделиться

На мой взгляд, вы пытаетесь немного усложнить себя, пытаясь вернуть значение NULL ...

Вместо этого сделайте что-то подобное:

class SomeError
{};
template <typename T>
    T Test<T>::FindItem(T item)
    {
        if(found) 
            //return original value, no problem here
        else
            throw(SomeError);
    }

Throwing пустой класс ничего не стоит ...

1
ответ дан 18 December 2019 в 05:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: