Конструктор с выводом аргумента шаблона выполняет неожиданное

#c #templates #constructor

#c #шаблоны #конструктор

Вопрос:

Проблема

Вызываемый конструктор (то есть A::A(T) ) выполняется не так, как я ожидал. Его вызов выполняет компиляцию (с использованием GCC-8.3.0), но, похоже, не выполняет std::cout operator<< . Почему это?

Код

 struct A {

    template <typename T>
    constexpr A(T) {
        std::cout << "A::A(T)";
    }
};

struct B {};

int main() {
    ::A a (B());
}
  

Зачем вам вообще это делать?

Я пытаюсь вывести тип T через вывод аргумента шаблона. Объект не имеет значения и, следовательно, безымянный. Мне требуется тип T для доступа к определенным данным во время компиляции (среди прочего для static_assert ). Насколько мне известно, в C невозможно явно указать аргумент шаблона в качестве параметра конструктора. (Итак: A a = A::A<T> ). Я мог бы сделать это косвенным способом, то есть создать статическую функцию-член для создания, где параметр может быть указан:

 struct C {
    template <typename T>
    static constexpr C create() { 
        // do whatever you want with T
        return C(); 
    }
};
  

Однако, я в основном просто экспериментирую.

Комментарии:

1. ::A a (B()); объявляет функцию с именем «a», которая принимает функцию без параметров (и без имени), которая возвращает a B , и возвращает A . (Существует много потенциальных дубликатов, но я не могу выбрать хороший.)

Ответ №1:

Вы столкнулись с самым неприятным синтаксическим анализом. Вместо этого вы должны определить a так:

 ::A a {B{}};