C++: Значения по умолчанию для аргументов шаблона кроме последних?

Я добавил бы:

Обеспечивают, реальная неподписка на нажимают на "Unsubscribe". Я видел, что реальные новостные рассылки предоставляют фиктивную ссылку неподписки, которая на шоу щелчка "была отписана успешно", но я все еще получу дальнейшие новостные рассылки.

5
задан Jeremy Friesner 1 August 2009 в 04:33
поделиться

5 ответов

In general, both in templates and functions or methods, C++ lets you use default for (and thereby omit) only trailing parameters -- no way out.

I recommend a template or macro to shorten AnObnoxiouslyLongSequenceOfCharacters to Foo -- not perfect, but better than nothing.

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

No. The closest you can come is to allow users to specify some sentinel type - like void - meaning "use default value here", and use template metamagic inside your class to typedef the real default if void was given to you. But this probably isn't a good idea from readability point of view.

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

Альтернативный вариант - использовать классы Traits:

template <class KeyType>
class KeyTraits
{
  typedef AnObnoxiouslyLongSequenceOfCharacters<KeyType> Compare;
};

template <class ValueType>
class ValueTraits
{
  typedef AnObnoxiouslyLongSequenceOfCharacters<ValueType>  Compare;
};

template<class KeyType class ValueType>
class MyClass
{
  typedef KeyTraits<KeyType>::Compare KeyCompareFunctor;
  typedef ValueTraits<ValueType>::Compare KeyCompareFunctor;
};

Затем, если у вас есть тип, который требует другой функции сравнения для Key, тогда вы должны явно специализировать тип KeyTraits для этого случая. Вот пример, в котором мы меняем его на int :

template <>
class KeyTraits<int>
{
  typedef SpecialCompareForInt Cmopare;
};
0
ответ дан 13 December 2019 в 05:39
поделиться

В вашем случае есть две основные возможности атаки:

  • Украдите строку подключения, а затем обратитесь к базе данных напрямую
  • Вызов методов в вашем коде C # напрямую без использования пользовательского интерфейса

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

Для прямого доступа к коду вы можете использовать защиту доступа к коду и обфускацию.

В вашем случае я бы не дал приложение Windows для прямого доступа к базе данных. Пусть приложение Windows вызывает службу WCF, служба WCF будет обращаться к базе данных.

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

Тот же подход можно применить к аргументам шаблона. Вместо того, чтобы иметь N аргументов шаблона + P необязательных, создайте свой класс с N + 1 аргументами шаблона. Последний будет содержать "именованные" параметры, которые можно опустить.

Этот ответ еще не завершен, но я надеюсь, что это хорошее начало!

3
ответ дан 13 December 2019 в 05:39
поделиться

There is another option, which uses inheritance and which works like the following. For the last two arguments, it uses a class that inherits virtually from a class that has two member templates, that can be used to generate the needed types. Because the inheritance is virtual, the typedefs it declares are shared among the inheritance as seen below.

template<class KeyType, 
         class ValueType, 
         class Pol1 = DefaultArgument, 
         class Pol2 = DefaultArgument>
class MyClass {
    typedef use_policies<Pol1, Pol2> policies;

    typedef KeyType key_type;
    typedef ValueType value_type;
    typedef typename policies::
      template apply_key_compare<KeyType>::type 
      key_compare;
    typedef typename policies::
      template apply_value_compare<ValueType>::type 
      value_compare;
};

Now, have a default argument that you use, which has typedefs for the default arguments you want provide. The member templates will be parameterized by the key and value types

struct VirtualRoot { 
  template<typename KeyType>
  struct apply_key_compare {
    typedef AnObnoxiouslyLongSequenceOfCharacters<KeyType> 
      type;
  };
  template<typename ValueType>
  struct apply_value_compare {
    typedef AnObnoxiouslyLongSequenceOfCharacters<ValueType> 
      type;
  };
};

struct DefaultArgument : virtual VirtualRoot { };

template<typename T> struct KeyCompareIs : virtual VirtualRoot {
  template<typename KeyType>
  struct apply_key_compare {
    typedef T type;
  };
};

template<typename T> struct ValueCompareIs : virtual VirtualRoot {
  template<typename ValueType>
  struct apply_value_compare {
    typedef T type;
  };
};

Now, use_policies will derive from all the template arguments. Where a derived class of VirtualRoot hides a member from the base, that member of the derived class is dominant over the member of the base, and will be used, even though the base-class member can be reached by other path in the inheritance tree.

Note that you don't pay for the virtual inheritance, because you never create an object of type use_policies. You only use virtual inheritance to make use of the dominance rule.

template<typename B, int>
struct Inherit : B { };

template<class Pol1, class Pol2>
struct use_policies : Inherit<Pol1, 1>, Inherit<Pol2, 2>
{ };

Because we potentially derive from the same class more than once, we use a class template Inherit: Inheriting the same class directly twice is forbidden. But inheriting it indirectly is allowed. You can now use this all like the following:

MyClass<int, float> m;
MyClass<float, double, ValueCompareIs< less<double> > > m;
0
ответ дан 13 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

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