LINUX.ORG.RU

История изменений

Исправление DarkEld3r, (текущая версия) :

Нет, это опасный путь - легко переборщить с гибкостью (пример: Перл).

Или лисп? (:

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

Еее... нет.

#include <iostream>

struct Base {
    virtual void foo() const {
        std::cout << "Base::foo" << std::endl;
    }
};

struct Derived : public Base {
    void foo() const override {
        std::cout << "Derived::foo" << std::endl;
    }
};

void reference(const Base& b) {
    b.foo();
}

void value(Base b) {
    b.foo();
}

int main()
{
  Derived d;
  reference(d);
  value(d);
}
Derived::foo
Base::foo
В том и дело, что если у нас есть значение (T), а не ссылка/указатель (T*/T&), то никакого полиморфизма не будет. Это и есть «точно Т». Другое дело, что передача по значению в сигнатуре функции означает копирование.

А ещё проверку на «полное соответствие» можно изобразить и через static_assert, правда придётся использовать шаблоны.

Исправление DarkEld3r, :

Нет, это опасный путь - легко переборщить с гибкостью (пример: Перл).

Или лисп? (:

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

Еее... нет.

#include <iostream>

struct Base {
    virtual void foo() const {
        std::cout << "Base::foo" << std::endl;
    }
};

struct Derived : public Base {
    void foo() const override {
        std::cout << "Derived::foo" << std::endl;
    }
};

void reference(const Base& b) {
    b.foo();
}

void value(Base b) {
    b.foo();
}

int main()
{
  Derived d;
  reference(d);
  value(d);
}
Derived::foo
Base::foo
В том и дело, что если у нас есть значение (T), а не ссылка/указатель (T*/T&), то никакого полиморфизма не будет. Это и есть «точно Т». Другое дело, что передача по значению в сигнатуре функции означает копирование.

Исходная версия DarkEld3r, :

Нет, это опасный путь - легко переборщить с гибкостью (пример: Перл).

Или лисп? (:

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

Еее... нет.

#include <iostream>

struct Base {
    virtual void foo() const {
        std::cout << "Base::foo" << std::endl;
    }
};

struct Derived : public Base {
    void foo() const override {
        std::cout << "Derived::foo" << std::endl;
    }
};

void reference(const Base& b) {
    b.foo();
}

void value(Base b) {
    b.foo();
}

int main()
{
  Derived d;
  reference(d);
  value(d);
}
Derived::foo
Base::foo
В том и дело, что если у нас есть значение (T), а не ссылка/указатель (T*/T&), то никакого полиморфизма не будет. Это и есть «точно Т».