Почему бы не вывести шаблонный параметр от конструктора?

Этот URL возвращает игроку фактический video_id

https://www.youtube.com/embed/live_stream?channel=UCkA21M22vGK9GtAvq3DvSlA

Где UCkA21M22vGK9GtAvq3DvSlA - идентификатор вашего канала. Вы можете найти его в аккаунте YouTube по ссылке «Мой канал».

101
задан Trevor Hickey 28 April 2016 в 03:46
поделиться

9 ответов

Я думаю, что это недопустимо, потому что конструктор не всегда является единственной точкой входа в класс (я говорю о конструкторе копирования и операторе =). Итак, предположим, что вы используете свой класс следующим образом:

MyClass m(string s);
MyClass *pm;
*pm = m;

Я не уверен, что для парсера было бы настолько очевидно знать, какой тип шаблона является MyClass pm;

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

C ++ 17

Принято, что C ++ 17 будет иметь вывод типа из аргументов конструктора.

Примеры:

std::pair p(2, 4.5);
std::tuple t(4, 3, 2.5);

Принятый документ .

45
ответ дан 24 November 2019 в 04:44
поделиться

Предположим, что компилятор поддерживает то, что вы просили. Тогда этот код действителен:

Variable v1( 10); // Variable<int>

// Some code here

Variable v2( 20.4); // Variable<double>

Теперь у меня одно и то же имя типа (Variable) в коде для двух разных типов (Variable и Variable). С моей субъективной точки зрения, это очень сильно влияет на читабельность кода. Наличие одного и того же имени типа для двух разных типов в одном пространстве имен меня вводит в заблуждение.

Позднее обновление: Еще одна вещь, которую следует учитывать: частичная (или полная) специализация шаблона.

Что, если я специализируюсь на переменной и не предоставлю конструктор, как вы ожидаете?

Итак, у меня будет:

template<>
class Variable<int>
{
// Provide default constructor only.
};

Тогда у меня будет код:

Variable v( 10);

Что должен делать компилятор? Используйте определение общего класса Variable, чтобы сделать вывод, что это Variable, а затем обнаружить, что Variable не предоставляет один конструктор параметров?

9
ответ дан 24 November 2019 в 04:44
поделиться

По-прежнему отсутствует: это делает следующий код довольно неоднозначным:

int main()
{
    int num = 2;
    Variable var(num);  // If equivalent to Variable<int> var(num),
    Variable var2(var); //Variable<int> or Variable<Variable<int>> ?
}
11
ответ дан 24 November 2019 в 04:44
поделиться

Многие классы не зависят от параметров конструктора. Есть только несколько классов, которые имеют только один конструктор и параметризуются на основе типа (ов) этого конструктора.

Если вам действительно нужен вывод шаблона, используйте вспомогательную функцию:

template<typename obj>
class Variable 
{
      obj data;
public: 
      Variable(obj d)
      : data(d)
      { }
};

template<typename obj>
inline Variable<obj> makeVariable(const obj& d)
{
    return Variable<obj>(d);
}
2
ответ дан 24 November 2019 в 04:44
поделиться

Выведение типов ограничено шаблонными функциями в текущем C ++, но уже давно поняли, что вывод типов в других контекстах будет очень полезен. Следовательно, C ++ 0x auto .

Хотя точно то, что вы предлагаете, будет невозможно в C ++ 0x, следующее показывает, что вы можете довольно близко подойти:

template <class X>
Variable<typename std::remove_reference<X>::type> MakeVariable(X&& x)
{
    // remove reference required for the case that x is an lvalue
    return Variable<typename std::remove_reference<X>::type>(std::forward(x));
}

void test()
{
    auto v = MakeVariable(2); // v is of type Variable<int>
}
1
ответ дан 24 November 2019 в 04:44
поделиться

Давайте посмотрим на проблему со ссылкой на класс, с которым все должны быть знакомы - std :: vector.

Во-первых, очень распространенное использование вектора - это использование конструктора, который не принимает параметров:

vector <int> v;

В этом случае, очевидно, невозможен вывод.

Второе распространенное использование - создание вектора с предварительно заданным размером :

vector <string> v(100);

Здесь, если был использован вывод:

vector v(100);

мы получаем вектор целых чисел, не строки, и предположительно он не имеет размера!

Наконец, рассмотрим конструкторы, которые принимают несколько параметров - с «выводом»:

vector v( 100, foobar() );      // foobar is some class

Какой параметр следует использовать для вывода? Нам понадобится какой-то способ сообщить компилятору, что он должен быть вторым.

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

-1
ответ дан 24 November 2019 в 04:44
поделиться

Вы правы, компилятор может легко догадаться, но, насколько мне известно, этого нет в стандарте или C ++ 0x, поэтому вам придется подождать еще как минимум 10 лет (стандарты ISO исправлены скорость поворота), прежде чем поставщики компиляторов добавят эту функцию

0
ответ дан 24 November 2019 в 04:44
поделиться

Сделав ctor шаблоном, переменная может иметь только одну форму , но разные ctors:

class Variable {
      obj data; // let the compiler guess
      public:
      template<typename obj>
      Variable(obj d)
       {
           data = d;
       }
};

int main()
{
    int num = 2;
    Variable var(num);  // Variable::data int?

    float num2 = 2.0f;
    Variable var2(num2);  // Variable::data float?
    return 0;         
}

Видите? Мы не можем иметь несколько членов Variable :: data.

-2
ответ дан 24 November 2019 в 04:44
поделиться

Для получения дополнительной информации см. Выведение аргументов шаблона C ++ .

-2
ответ дан 24 November 2019 в 04:44
поделиться
Другие вопросы по тегам:

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