Вот мое суждение в C++
, я пытался ввести такое небольшое ограничение на тип итератора, как я мог так это решение принимать просто вперед итератор, и это может быть const_iterator. Это должно работать с любым стандартным контейнером. В случаях, где аргументы не имеют смысла, он бросает станд.:: invalid_argumnent
#include <vector>
#include <stdexcept>
template <typename Fci> // Fci - forward const iterator
std::vector<std::vector<Fci> >
enumerate_combinations(Fci begin, Fci end, unsigned int combination_size)
{
if(begin == end && combination_size > 0u)
throw std::invalid_argument("empty set and positive combination size!");
std::vector<std::vector<Fci> > result; // empty set of combinations
if(combination_size == 0u) return result; // there is exactly one combination of
// size 0 - emty set
std::vector<Fci> current_combination;
current_combination.reserve(combination_size + 1u); // I reserve one aditional slot
// in my vector to store
// the end sentinel there.
// The code is cleaner thanks to that
for(unsigned int i = 0u; i < combination_size && begin != end; ++i, ++begin)
{
current_combination.push_back(begin); // Construction of the first combination
}
// Since I assume the itarators support only incrementing, I have to iterate over
// the set to get its size, which is expensive. Here I had to itrate anyway to
// produce the first cobination, so I use the loop to also check the size.
if(current_combination.size() < combination_size)
throw std::invalid_argument("combination size > set size!");
result.push_back(current_combination); // Store the first combination in the results set
current_combination.push_back(end); // Here I add mentioned earlier sentinel to
// simplyfy rest of the code. If I did it
// earlier, previous statement would get ugly.
while(true)
{
unsigned int i = combination_size;
Fci tmp; // Thanks to the sentinel I can find first
do // iterator to change, simply by scaning
{ // from right to left and looking for the
tmp = current_combination[--i]; // first "bubble". The fact, that it's
++tmp; // a forward iterator makes it ugly but I
} // can't help it.
while(i > 0u && tmp == current_combination[i + 1u]);
// Here is probably my most obfuscated expression.
// Loop above looks for a "bubble". If there is no "bubble", that means, that
// current_combination is the last combination, Expression in the if statement
// below evaluates to true and the function exits returning result.
// If the "bubble" is found however, the ststement below has a sideeffect of
// incrementing the first iterator to the left of the "bubble".
if(++current_combination[i] == current_combination[i + 1u])
return result;
// Rest of the code sets posiotons of the rest of the iterstors
// (if there are any), that are to the right of the incremented one,
// to form next combination
while(++i < combination_size)
{
current_combination[i] = current_combination[i - 1u];
++current_combination[i];
}
// Below is the ugly side of using the sentinel. Well it had to haave some
// disadvantage. Try without it.
result.push_back(std::vector<Fci>(current_combination.begin(),
current_combination.end() - 1));
}
}
«это» - позднее связывание. то есть он привязывается к объекту непосредственно перед выполнением функции. То, к чему он привязан, зависит от того, как вы вызываете свою функцию.
, если вы вызываете его как (вызов функции):
myfunction();
"this" привязывается к глобальному объекту
, если вы вызываете его как (вызов метода) :
myobject.myfunction();
"this" привязывается к "myobject"
, вы также можете назвать его так (вызов вызова):
myfunction.call(myobject);
в этом случае "this" привязывается к myobject
, также есть (вызов конструктора ):
new MyFunction();
, в котором «this» привязывается к вновь созданному пустому объекту, прототипом которого является MyFunction.prototype.
, по крайней мере, так говорят об этом создатели javascript. (и я думаю, что это обсуждается именно так в спецификации) Различные способы вызова функции.
новая версия стандарта ecmascript (ecmascript5) включает метод «bind» библиотеки прототипов, который возвращает новую функцию с «this», предварительно привязанным к тому, что вы укажете. например:
mynewfunction = myfunction.bind(myobject);
mynewfunction();
при вызове mynewfunction this уже привязано к myobject.
You're right it wasn't valid javascript. I was thinking of using new function which allows you to have multiple instances:
function o2(value) {
var _this = this;
this.field = value;
this.method = function() {
return _this.field;
};
}
var test1 = new o2('blah');
var test2 = new o2('meh');
var callback1 = test1.method;
var callback2 = test2.method;
alert(callback1());
alert(callback2());
Alternatively if you want to continue using a singleton you can reference o from within the object.
var o = {
field : 'value',
method : function() {
return o.field;
}
};
Вы можете указать контекст this
, например, когда вы вызываете метод через .apply ()
или .call ()
методы. В вашем случае, как вы сказали, контекст изменился. Если вам действительно нужно сделать field
значением o.field
, вы должны указать это явно, например, используя закрытие при определении вашего метода method
.