Nano Hash - криптовалюты, майнинг, программирование

Передача безымянных классов через функции

Как передать этот экземпляр в качестве параметра в функцию?

class
{
    public:
    void foo();
} bar;

Должен ли я называть класс?
Его можно копировать, поскольку я не сделал его копирующий ctor приватным.
Так как же это возможно, если вообще возможно?

13.06.2009

Ответы:


1

Может быть, было бы лучше, если бы вы указали, что вы хотите сделать. Почему вы хотите создать безымянный класс? Соответствует ли он интерфейсу? Безымянные классы довольно ограничены, их нельзя использовать в качестве параметров функций, их нельзя использовать в качестве типовых параметров шаблонов...

Теперь, если вы реализуете интерфейс, вы можете передать ссылки на этот интерфейс:

class interface {
public:
   virtual void f() const = 0;
};
void function( interface const& o )
{
   o.f();
}
int main()
{
   class : public interface {
   public:
      virtual void f() const {
         std::cout << "bar" << std::endl;
      }
   } bar;
   function( bar ); // will printout "bar"
}

ПРИМЕЧАНИЕ. Для всех тех ответов, которые рассматривают аргументы шаблона как вариант, безымянные классы нельзя передавать в качестве аргументов типа шаблона.

Стандарт С++. 14.3.1, пункт 2:

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

При тестировании с помощью компилятора comeau (ссылка для онлайн-тестирования) вы получите следующую ошибку. :

ошибка: аргумент шаблона не может ссылаться на безымянный тип

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

ПРИМЕЧАНИЕ. Comeau и gcc (g++ 4.0) выдают ошибку с приведенным выше кодом. Компилятор Intel (и из комментариев других людей MSVS 2008) допускает использование неназванных классов в качестве параметров шаблона в отличие от стандарта.

13.06.2009
  • Я спрашиваю, потому что изучаю некоторые функции C++, которые я почти никогда не видел в использовании. Так в чем же разница между безымянным классом и синглтоном? 14.06.2009
  • У них нет ничего общего. Шаблон singleton имеет дело с уникальностью элемента (один объект, доступный из любого места). Вы можете реализовать синглтон (как и все остальные) с именованными классами. 14.06.2009
  • К вашему сведению: это ненужное ограничение на локальные классы и безымянные типы в качестве параметров шаблона было снято с C++0x :) 14.06.2009

  • 2

    Зачем вам создавать анонимный класс, если вы хотите передать его функции?

    Просто явно объявите класс:

    class Foo {
      // ...
    };
    
    void Method(Foo instance); 
    
    int main() {
        Foo bar;
        Method(bar);
    }
    

    Второй возможностью будет использование функции-шаблона, поэтому компилятор выведет тип (обратите внимание, что это несовместимо со стандартом!)

    #include <iostream>
    
    using namespace std;
    
    template <typename T>
    void SayFoo(T& arg) {
        arg.Foo();
    }
    
    int main() {
    
        class {
        public: 
            void Foo() { cout << "Hi" << endl; }
        } Bar;
    
        Bar.Foo();
    
        SayFoo(Bar);
    
        return 0;
    }
    

    Нет проблем с копированием класса, поскольку компилятор автоматически сгенерировал конструктор копирования, и вы можете использовать такие инструменты, как boost::typeof, чтобы избежать явного обращения к типу.

    BOOST::AUTO(copy, Bar);
    

    Другой подход использует (относительно медленный) полиморфизм времени выполнения (интерфейсы/наследование).

    13.06.2009
  • не могли бы вы показать мне пример использования boost::typeof? BOOST::AUTO мало что мне говорит. Это все еще необходимо с новым стандартом? 13.06.2009
  • Вариант 2 не вариант. Из стандартных аргументов типа шаблона 14.3.1: «2 Локальный тип, тип без привязки, безымянный тип или тип, составной из любого из этих типов, не должны использоваться в качестве аргумента шаблона для параметра типа шаблона». 13.06.2009
  • @the_drow: Нет, C++0x введет ключевое слово auto, которое автоматически определит тип. Вам нужно будет установить boost, чтобы использовать boost:: typeof 13.06.2009

  • 3

    Да, вы должны назвать класс, чтобы передать его экземпляр функции. Поскольку вы не предоставили свой собственный компилятор copy ctor, он сгенерирует свой собственный и будет использовать его.

    13.06.2009

    4

    Ммм, безымянный класс.

    Вы можете передать указатель на него как void *.

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

    РЕДАКТИРОВАТЬ: вы все равно можете передать его функции шаблона, которая может его скопировать.

    REEDIT: редактирование было неправильным.

    13.06.2009
  • Нет, не может. 14.3.1 Аргументы типа шаблона: «2 Локальный тип, тип без связи, безымянный тип или тип, составной из любого из этих типов, не должны использоваться в качестве аргумента шаблона для параметра типа шаблона». 13.06.2009
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..