Выбор конструктора для вызова - PullRequest
0 голосов
/ 26 февраля 2020

Рассмотрим следующий код

class MyClass
{
public:
    MyClass( MyClass && );
    template< typename ... T > MyClass( T&& ... );
};

Как различить вызов между этими двумя конструкторами? Могу ли я специализировать шаблонный шаблон только для вызова оригинала?

Вот пример использования (и это именно то, что я делаю в моем реальном коде):

MyClass c( MyClass { } );

Ответы [ 2 ]

5 голосов
/ 26 февраля 2020

Начиная с C ++ 17

MyClass c( MyClass { } );

всегда будет вызывать

template< typename ... T > MyClass( T&& ... );

Причина этого в том, что временного объекта больше нет. Вместо этого инициализация исключается, и c напрямую создается из инициализатора «временного». Это означает, что у вас действительно есть

MyClass c{};

Это хорошо, хотя вместо того, чтобы строить и двигаться, мы просто создаем, что является выигрышем в производительности.

0 голосов
/ 27 февраля 2020

Вот дополнение к ответу Натана, поскольку вы его еще не приняли.

#include <iostream>

class MyClass
{
public:
    MyClass() {
        std::cout << "default\n";
    }

    MyClass(MyClass&& rhs) {
        std::cout<< "moving\n";
    }

    template<typename ... T >
    MyClass(T&& ... ts) {
        std::cout << "ctor template\n";
    }
};

int main()
{ 
    MyClass a(MyClass{});       // only default ctor, no move
    std::cout << "---\n";
    MyClass b(MyClass{"bork"}); // only template ctor, no move
    std::cout << "---\n";
    MyClass c = std::move(a);   // plain move
}

Демо

...