Шаблонные специализации требуют шаблона <> синтаксис?

У меня нет тестовой машины. То есть я не могу ни копировать среду клиента, ни пытаться установить приложение на «чистую» систему, чтобы ловить ошибки перед отправкой.

Этот тип настройки обычно никогда не заканчивается хорошо. Независимо от того, насколько вы хороши, всегда будут существенные различия между машинами разработчика и машинами заказчика. С одной стороны, Visual Studio имеет тенденцию включать в себя кучу времени выполнения, от которого ваше приложение может зависеть, ничего не сказав. Настройка виртуальной машины не очень сложна. Я использую VMWare Workstation для эмуляции всех видов различных машин. Единственное требование - наличие лицензий на операционные системы и программы, которые вы хотите установить на виртуальных машинах. VMWare предлагает 30-дневную бесплатную пробную версию, и после этого я считаю, что $ 189.

8
задан Drew Dormann 2 June 2009 в 00:52
поделиться

5 ответов

Ваш код не является специализированным шаблоном, а скорее не является шаблонной функцией. Здесь есть некоторые отличия. Оператор без шаблона () будет иметь приоритет над шаблонной версией (для точного совпадения, но преобразования типов там не будут), но вы все равно можете принудительно вызвать шаблонную функцию:

class Visitor
{
public: // corrected as pointed by stefanB, thanks
   template <typename T>
   void operator()( T data ) {
      std::cout << "generic template" << std::endl;
   }
   void operator()( bool data ) {
      std::cout << "regular member function" << std::endl;
   }
};
template <> // Corrected: specialization is a new definition, not a declaration, thanks again stefanB 
void Visitor::operator()( int data ) {
   std::cout << "specialization" << std::endl;
}
int main()
{
   Visitor v;
   v( 5 ); // specialization
   v( true ); // regular member function
   v.operator()<bool>( true ); // generic template even if there is a non-templated overload
   // operator() must be specified there (signature of the method) for the compiler to 
   //    detect what part is a template. You cannot use <> right after a variable name
}

В вашем коде нет большая разница, но если ваш код должен передать тип параметра шаблона, он станет смешнее:

template <typename T>
T g() { 
   return T();
}
template <>
int g() {
   return 0;
}
int g() {
   return 1;
}
int main()
{
   g<double>(); // return 0.0
   g<int>(); // return 0
   g(); // return 1 -- non-templated functions take precedence over templated ones
}
19
ответ дан 5 December 2019 в 05:19
поделиться

Здесь происходит перегрузка функций; чтобы получить специализацию шаблона, вам действительно понадобится синтаксис template <> . Однако вы должны знать, что эти два подхода, даже если они могут казаться идентичными, тонко отличаются, и даже компилятор может потеряться при выборе правильной функции для вызова. Перечисление всех возможных случаев было бы слишком длинным для этого ответа, но вы можете проверить Herb Sutter GoTW # 49 по этой теме.

5
ответ дан 5 December 2019 в 05:19
поделиться

Вы сделали не сериализацию шаблона, а перегрузку функций. Это безопасно.

PS Трудно сказать, правильно это или нет, не зная, чего вы пытаетесь достичь. Имейте в виду, что независимо от того, шаблон это или перегруженная функция, ваш оператор будет выбран во время компиляции. Если вам нужна диспетчеризация во время выполнения, вам нужен полиморфизм, а не перегрузка. Ну, вы, наверное, все равно это знаете; на всякий случай.

2
ответ дан 5 December 2019 в 05:19
поделиться

О, он скомпилируется. Это просто не будет функцией шаблона. У вас будет обычная функция, не являющаяся шаблоном, вместо специализации шаблона.

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

4
ответ дан 5 December 2019 в 05:19
поделиться

У вас есть

  • void operator () (bool b) , который не шаблонная функция
  • template void оператор () (T t) , который является отдельным базовый шаблон, который перегружает выше

У вас может быть полная специализация второго, как в template <> void operator (int i) , который будет учитываться только тогда, когда void operator () (bool b) не соответствует.

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

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

В итоге :

  1. Не являются шаблонными функциями считается первым (это ваша равнина operator () (bool) выше)
  2. Проверяются базовые шаблоны функций второй (это ваш шаблонный функция), выбирается наиболее специализированный базовый шаблон, а затем, если он имеет специализацию для конкретных типов, используется эта специализация, в противном случае базовый шаблон используется с «правильными» типами (см. объяснение в статье)

Пример:

#include <iostream>
using namespace std;

struct doh
{
    void operator()(bool b)
    {
        cout << "operator()(bool b)" << endl;
    }

    template< typename T > void operator()(T t)
    {
        cout << "template <typename T> void operator()(T t)" << endl;
    }
};
// note can't specialize inline, have to declare outside of the class body
template<> void doh::operator()<>(int i)
{
    cout << "template <> void operator()<>(int i)" << endl;
}
template<> void doh::operator()<>(bool b)
{
    cout << "template <> void operator()<>(bool b)" << endl;
}

int main()
{
    doh d;
    int i;
    bool b;
    d(b);
    d(i);
}

Вы получаете вызовы:

operator()(bool b)       <-- first non template method that matches
template <> void operator()(int i)     <-- the most specialized specialization of templated function is called
2
ответ дан 5 December 2019 в 05:19
поделиться
Другие вопросы по тегам:

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