问:
How to manage UIbutton in UItableViewCell without using sender.tag method?
I have a cell with a button inside. In my cellForRowAtIndexPath method i refeer to my uibutton in this way:

```<code>UIButton *Button= (UIButton *) [cell viewWithTag:3];
</code>```

I have found a solution, something like this:

```<code>Button.tag = indexPath.row;

[Button addTarget:self action:@selector(yourButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

-(void)yourButtonClicked:(UIButton*)sender
{
     if (sender.tag == 0)
     {
         // Your code here
     }
}
</code>```

But my button.tag is already used to identify the UIbutton view from the others views inside the cell, i can't use it for the indexpath.row. How i can do in my case?

EDIT

Finally i have made a Category for the UIButton, it seems the faster ad reusable solutions but every answers here is a valid option

答:
You need not access the button using tag and then set Selectorfor each cell. I believe you can achieve much cleaner approach

Step 1:

In your Custom cell, drag the IBAction from button in cell to your custom cell.

```<code>@IBAction func buttonTapped(_ sender: Any) {
   //wait for implementation
}
</code>```

Step 2:

In your custom cell, now declare a protocol

```<code>protocol CellsProtocol : NSObjectProtocol {
    func buttonTapped(at index : IndexPath)
}
</code>```

and while in being same class, create few variables as well.

```<code>weak var delegate : CellsProtocol? = nil
var indexPath : IndexPath! = nil
</code>```

we will see the usage of these variables soon :)

Step 3:

Lets get back to IBAction we dragged just now

```<code>@IBAction func buttonTapped(_ sender: Any) {
     self.delegate?.buttonTapped(at: self.indexPath)
}
</code>```

Step 4:

Now you can get back to your UITableViewController and confirm to the protocol you declared just now

```<code>extension ViewController : CellsProtocol {
    func buttonTapped(at index: IndexPath) {
        //here you have indexpath of cell whose button tapped
    }
}
</code>```

Step 5:

Now finally update your cellForRowAtIndexPath as

```<code>extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell : MyTableViewCell = ;
        cell.indexPath = indexPath
        cell.delegate = self
    }
}
</code>```

Thats it :) Now you have a button action which tells you, button in which cell tapped :) Hope it helps :) This is more generic approach, because even if you have multiple uicomponents you can still use this approach.

EDIT 1:

In comments below rmaddy pointed out that having a indexPath as a property cell might lead to issues and cell should not care to know its indexPath and protocol should be modified to return the cell rather than returning the index path.

Quoting comment :

Not necessarily. You are assuming reloadData is being called. You can
  have a visible cell and then insert a row above it. That visible cell
  is not updated and its indexPath is not different but the cell's
  indexPath property that you have is not updated. Use the cell itself
  as the argument. It's much better than passing the index path. If the
  index path is needed by the delegate, the delegate can ask the table
  view what the cell's current index path is. A cell should never care
  or know what its index path is.

The statement above makes sense especially the fact that A cell should never care  or know what its index path is. Hence updating my answer below

Step 1:

Go ahead and delete the indexPath property in cell :)

Step 2:

Modify protocol to

```<code>protocol CellsProtocol : NSObjectProtocol {
    func buttonTapped(in cell : UITableViewCell)
}
</code>```

Step 3:

Modify your IBAction as

```<code>@IBAction func buttonTapped(_ sender: Any) {
    self.delegate?.buttonTapped(in: self)
}
</code>```

Step 4:

Finally modify your protocol confirmation in your ViewController to

```<code>extension ViewController : CellsProtocol {

    func buttonTapped(in cell: UITableViewCell) {
        let indexPath = self.tableView.indexPath(for: cell)
        //here you have indexpath of cell whose button tapped
    }
}
</code>```

Thats it :)

Body:
I have a cell with a button inside. In my cellForRowAtIndexPath method i refeer to my uibutton in this way:

UIButton *Button= (UIButton *) [cell viewWithTag:3];

I have found a solution, something like this:

Button.tag = indexPath.row;

[Button addTarget:self action:@selector(yourButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

-(void)yourButtonClicked:(UIButton*)sender
{
     if (sender.tag == 0)
     {
         // Your code here
     }
}

But my button.tag is already used to identify the UIbutton view from the others views inside the cell, i can't use it for the indexpath.row. How i can do in my case?

EDIT

Finally i have made a Category for the UIButton, it seems the faster ad reusable solutions but every answers here is a valid option

Body:
You need not access the button using tag and then set Selectorfor each cell. I believe you can achieve much cleaner approach

Step 1:

In your Custom cell, drag the IBAction from button in cell to your custom cell.

@IBAction func buttonTapped(_ sender: Any) {
   //wait for implementation
}

Step 2:

In your custom cell, now declare a protocol

protocol CellsProtocol : NSObjectProtocol {
    func buttonTapped(at index : IndexPath)
}

and while in being same class, create few variables as well.

weak var delegate : CellsProtocol? = nil
var indexPath : IndexPath! = nil

we will see the usage of these variables soon :)

Step 3:

Lets get back to IBAction we dragged just now

@IBAction func buttonTapped(_ sender: Any) {
     self.delegate?.buttonTapped(at: self.indexPath)
}

Step 4:

Now you can get back to your UITableViewController and confirm to the protocol you declared just now

extension ViewController : CellsProtocol {
    func buttonTapped(at index: IndexPath) {
        //here you have indexpath of cell whose button tapped
    }
}

Step 5:

Now finally update your cellForRowAtIndexPath as

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell : MyTableViewCell = ;
        cell.indexPath = indexPath
        cell.delegate = self
    }
}

Thats it :) Now you have a button action which tells you, button in which cell tapped :) Hope it helps :) This is more generic approach, because even if you have multiple uicomponents you can still use this approach.

EDIT 1:

In comments below rmaddy pointed out that having a indexPath as a property cell might lead to issues and cell should not care to know its indexPath and protocol should be modified to return the cell rather than returning the index path.

Quoting comment :

Not necessarily. You are assuming reloadData is being called. You can
  have a visible cell and then insert a row above it. That visible cell
  is not updated and its indexPath is not different but the cell's
  indexPath property that you have is not updated. Use the cell itself
  as the argument. It's much better than passing the index path. If the
  index path is needed by the delegate, the delegate can ask the table
  view what the cell's current index path is. A cell should never care
  or know what its index path is.

The statement above makes sense especially the fact that A cell should never care  or know what its index path is. Hence updating my answer below

Step 1:

Go ahead and delete the indexPath property in cell :)

Step 2:

Modify protocol to

protocol CellsProtocol : NSObjectProtocol {
    func buttonTapped(in cell : UITableViewCell)
}

Step 3:

Modify your IBAction as

@IBAction func buttonTapped(_ sender: Any) {
    self.delegate?.buttonTapped(in: self)
}

Step 4:

Finally modify your protocol confirmation in your ViewController to

extension ViewController : CellsProtocol {

    func buttonTapped(in cell: UITableViewCell) {
        let indexPath = self.tableView.indexPath(for: cell)
        //here you have indexpath of cell whose button tapped
    }
}

Thats it :)


来源: stackexchange

问:
Questions about operator overloading
I have two questions about operator overloading.

For an iterator type, how is operator-> overloaded? What value should it return assuming that it is an iterator for a collection of class T objects?

Why does operator++() return by class T& while operator++(int) return by class T? I understand these two represent prefix increment and postfix increment. But why the difference in return value?

EDIT: For Alf. Code is not complete though functioning. Any suggestions for improvement are welcome.

```<code>#ifndef DHASH_H
#define DHASH_H

//#include <vector>
#include <memory>
#include <exception>
#include <new>
#include <algorithm>
#include <functional>

namespace MCol
{
    template <typename KEY, typename VALUE, typename HASH_FUNCTION, typename KEY_COMP = std::equal_to<KEY> >
        class hash_container
        {
            private:
                struct entry
                {
                    KEY _k;
                    VALUE _v;

                    entry(const KEY& k, const VALUE& v)
                        :_k(k), _v(v)
                    {}

                    entry& operator=(const entry& e)
                    {
                        this->_k = e._k;
                        this->_v = e._v;
                    }
                };

            private:
                struct bucket
                {
                    entry* a_Entries;
                    size_t sz_EntryCount;

                    bucket()
                    {
                        sz_EntryCount = 0;
                        a_Entries = NULL;
                    }

                    ~bucket()
                    {
                        for(size_t szI = 0; szI < sz_EntryCount; ++szI)
                        {
                            a_Entries[szI].~entry();
                        }
                        free(a_Entries);
                    }

                    //Grow by 1. (Perhaps later try block increment. But wikipedia suggests that there is little difference between the two)
                    inline bool insert(const KEY& k, const VALUE& v) throw (std::bad_alloc)
                    {
                        if(find(k) != NULL)
                        {
                            return false;
                        }
                        a_Entries = static_cast<entry*>(realloc(a_Entries, sizeof(entry)*(++sz_EntryCount)));
                        if(a_Entries == NULL)
                        {
                            throw std::bad_alloc();
                        }

                        new (&a_Entries[sz_EntryCount - 1]) entry(k, v);
                        return true;
                    }

                    //Find entry, swap with last valid entry, remove if necessary.
                    inline bool erase(const KEY& k) throw(std::bad_alloc)
                    {
                        //Forwards or backwards? My guess is backwards is better.
                        entry* pE = a_Entries;
                        while(pE != a_Entries + sz_EntryCount)
                        {
                            if(pE->_k == k)
                            {
                                break;
                            }
                            ++pE;
                        }

                        if(pE == a_Entries + sz_EntryCount)
                        {
                            return false;
                        }

                        //We don't need to swap if the entry is the only one in the bucket or if it is the last one.
                        entry* pLast = a_Entries + sz_EntryCount - 1;
                        if((sz_EntryCount > 1) && (pE != pLast))
                        {
                            pE = pLast;
                        }

                        a_Entries = static_cast<entry*>(realloc(a_Entries, sizeof(entry)*(--sz_EntryCount)));
                        if(a_Entries == NULL && sz_EntryCount > 0)
                        {
                            throw std::bad_alloc();
                        }

                        return true;
                    }

                    inline entry* find(const KEY& k) throw()
                    {
                        //Better implement a search policy.
                        entry* pE = a_Entries;
                        while(pE != a_Entries + sz_EntryCount)
                        {
                            if(pE->_k == k)
                            {
                                break;
                            }
                            ++pE;
                        }

                        if(pE == a_Entries + sz_EntryCount)
                        {
                            return NULL;
                        }

                        return pE;
                    }
                };

                HASH_FUNCTION& _hf;
                KEY_COMP _kc;

                size_t sz_TableSize;
                double d_MultFactor;                                            //Recalculate this as 1/sz_TableSize everytime sz_TableSize changes.
                size_t sz_NextResizeLimit;
                size_t sz_EntryCount;
                double d_ExpectedLoadFactor;
                double d_CurrentLoadFactor;

                //If the load factor is relatively high (say >0.5 assuming sizeof(entry) == 2*sizeof(size_t)), it is more space efficient to keep a straight bucket array. But if the load factor is low, memory consumption would be lower if a pointer array of Entries is used here. But, because we would not be much concerned with a little additional memory being used when there are few entries, I think array of bucket objects is better. Further, it bypasses a pointer lookup. May have to reconsider is a situation where multiple hash tables are used (Perhaps as an array).
                bucket* a_Buckets;

                hash_container(const hash_container&);
                hash_container& operator=(const hash_container&);

                inline void calculateMultFactor() throw()
                {
                    d_MultFactor = 1.0f/static_cast<double>(sz_TableSize + 1);
                    //sz_NextResizeLimit = static_cast<size_t>(d_ExpectedLoadFactor*sz_TableSize);
                    //Have a look at this.
                    //TODO
                }

                void resize(size_t szNewSize) throw(std::bad_alloc)
                {
                    if(szNewSize == 0)
                    {
                        szNewSize = 1;
                    }
                    size_t szOldSize = sz_TableSize;
                    for(size_t szI = szNewSize; szI < szOldSize; ++szI)
                    {
                        a_Buckets[szI].~bucket();
                    }

                    a_Buckets = static_cast<bucket*>(realloc(a_Buckets, sizeof(bucket)*szNewSize));
                    if(a_Buckets == NULL)
                    {
                        throw std::bad_alloc();
                    }
                    //Unnecessary at the moment. But, just in case that bucket changes.
                    for(size_t szI = szOldSize; szI < szNewSize; ++szI)
                    {
                         new (&a_Buckets[szI]) bucket();
                    }

                    sz_TableSize = szNewSize;
                    calculateMultFactor();
                }

                inline bucket* get_bucket(const KEY& k) throw()
                {
                    return a_Buckets + _hf(k, sz_TableSize);
                }

                inline bool need_resizing() const throw()
                {

                }
            public:
                //typedef iterator void*;
                //typedef const_iterator void*;

                //iterator Insert(KEY& k, VALUE& v);
                //VALUE& Find(Key& k);
                //const VALUE& Find(Key& k);
                //iterator Find(KEY k);
                //const_iterator Find(KEY k);
                //void Delete(KEY& k);
                //void Delete(iterator it);
                //void Delete(const_iterator it);
                class iterator
                {
                    private:
                        entry* p_Entry;
                        bucket* p_Bucket;

                        friend class bucket;

                    public:
                        iterator(entry* pEntry)
                            :p_Entry(pEntry)
                        {
                        }

                        iterator()
                        {
                            p_Entry = NULL;
                        }

                        iterator(const iterator& it)
                        {
                            this->p_Entry = it.p_Entry;
                        }

                        inline VALUE& operator*() const
                        {
                            return p_Entry->_v;
                        }

                        inline bool operator==(const iterator& it) const
                        {
                            return this->p_Entry == it.p_Entry;
                        }

                        inline bool operator!=(const iterator& it) const
                        {
                            return !(*this == it);
                        }

                        inline iterator& operator=(const iterator& it)
                        {
                            this->p_Entry = it.p_Entry;
                        }

                        inline VALUE* operator->() const
                        {
                            return &p_Entry->_v;
                        }

                        inline iterator operator++()
                        {
                            return *this;
                        }

                        inline iterator& operator++(int)
                        {
                            //WRONG!!!
                            //TODO : Change this.
                            return *this;
                        }
                };

            private:
                iterator _EndIt;

            public:
                hash_container(HASH_FUNCTION& hf, size_t szTableSize = 1024, double dLoadFactor = 0.7f, KEY_COMP kc = KEY_COMP())throw(std::bad_alloc)
                    :_hf(hf), sz_TableSize(szTableSize), d_ExpectedLoadFactor(dLoadFactor), _kc(kc)
                {
                    if(d_ExpectedLoadFactor < 0.1f)
                    {
                        d_ExpectedLoadFactor = 0.1f;
                    }

                    a_Buckets = NULL;
                    sz_TableSize = 0;
                    if(szTableSize == 0)
                    {
                        szTableSize = 1;
                    }
                    resize(szTableSize);
                    d_CurrentLoadFactor = 0.0f;
                    sz_EntryCount = 0;

                    _EndIt = iterator(NULL);
                }

                virtual ~hash_container()
                {
                    for(size_t szI = 0; szI < sz_TableSize; ++szI)
                    {
                        a_Buckets[szI].~bucket();
                    }
                }

                inline iterator find(const KEY& k) throw()
                {
                    bucket* pBucket = get_bucket(k);
                    return pBucket->find(k);
                }

                inline bool insert(const KEY& k, const VALUE& v) throw(std::bad_alloc)
                {
                    bucket* pBucket = get_bucket(k);
                    bool bRet = false;
                    try
                    {
                        bRet = pBucket->insert(k, v);
                    }
                    catch(std::bad_alloc& e)
                    {
                        //What now?
                        throw e;
                    }
                    if(bRet == true)
                    {
                        ++sz_EntryCount;
                    }
                    return bRet;
                }

                inline VALUE& operator[](const KEY& k) throw(std::bad_alloc)
                {
                    bucket* pBucket = get_bucket(k);

                }

                inline bool erase(const KEY& k) throw(std::bad_alloc)
                {
                    bucket* pBucket =  get_bucket(k);
                    bool bRet = false;
                    try
                    {
                        bRet = pBucket->erase(k);
                    }
                    catch(std::bad_alloc& e)
                    {
                        throw e;
                    }
                    if(bRet == true)
                    {
                        --sz_EntryCount;
                    }
                    return bRet;
                }

                inline iterator end() const
                {
                    return _EndIt;
                }

                inline size_t size() const
                {
                    return sz_EntryCount;
                }

                inline size_t table_size() const
                {
                    return sz_TableSize;
                }

                inline double current_load_factor() const
                {
                    return d_MultFactor*static_cast<double>(sz_EntryCount);
                }

                inline double expected_load_factor() const
                {
                    return d_ExpectedLoadFactor;
                }
        };
}

#endif
</code>```

答:
.1. operator-> should almost always return a pointer type.  When acting as an iterator with value_type T, it should return T*.

In some rarer cases, operator-> may return a different class type, which also has an operator-> member function.

.2. There are no technical requirements on what either form of operator++ must return, but the usual conventions make them act most like the built-in meanings.

```<code>class T {
public:
    // pre-increment
    T& operator++() { increment_me(); return *this; }
    // post-increment
    T operator++(int) { T copy(*this); increment_me(); return copy; }
    //...
};
</code>```

The built-in meaning of the pre-increment expression ++x first increments the number and then returns an lvalue to the incremented number.  A return type of T& acts similarly.

The built-in meaning of the post-increment expression 'x++' increments the variable but returns an rvalue copy of the variable's previous value.  So most user-defined overloads return a copy of the original value (which can practically never be a reference).

ContentLicense: CC BY-SA 2.5

Title: Questions about operator overloading

Body:
I have two questions about operator overloading.

For an iterator type, how is operator-> overloaded? What value should it return assuming that it is an iterator for a collection of class T objects?

Why does operator++() return by class T& while operator++(int) return by class T? I understand these two represent prefix increment and postfix increment. But why the difference in return value?

EDIT: For Alf. Code is not complete though functioning. Any suggestions for improvement are welcome.

#ifndef DHASH_H
#define DHASH_H

//#include <vector>
#include <memory>
#include <exception>
#include <new>
#include <algorithm>
#include <functional>

namespace MCol
{
    template <typename KEY, typename VALUE, typename HASH_FUNCTION, typename KEY_COMP = std::equal_to<KEY> >
        class hash_container
        {
            private:
                struct entry
                {
                    KEY _k;
                    VALUE _v;

                    entry(const KEY& k, const VALUE& v)
                        :_k(k), _v(v)
                    {}

                    entry& operator=(const entry& e)
                    {
                        this->_k = e._k;
                        this->_v = e._v;
                    }
                };

            private:
                struct bucket
                {
                    entry* a_Entries;
                    size_t sz_EntryCount;

                    bucket()
                    {
                        sz_EntryCount = 0;
                        a_Entries = NULL;
                    }

                    ~bucket()
                    {
                        for(size_t szI = 0; szI < sz_EntryCount; ++szI)
                        {
                            a_Entries[szI].~entry();
                        }
                        free(a_Entries);
                    }

                    //Grow by 1. (Perhaps later try block increment. But wikipedia suggests that there is little difference between the two)
                    inline bool insert(const KEY& k, const VALUE& v) throw (std::bad_alloc)
                    {
                        if(find(k) != NULL)
                        {
                            return false;
                        }
                        a_Entries = static_cast<entry*>(realloc(a_Entries, sizeof(entry)*(++sz_EntryCount)));
                        if(a_Entries == NULL)
                        {
                            throw std::bad_alloc();
                        }

                        new (&a_Entries[sz_EntryCount - 1]) entry(k, v);
                        return true;
                    }

                    //Find entry, swap with last valid entry, remove if necessary.
                    inline bool erase(const KEY& k) throw(std::bad_alloc)
                    {
                        //Forwards or backwards? My guess is backwards is better.
                        entry* pE = a_Entries;
                        while(pE != a_Entries + sz_EntryCount)
                        {
                            if(pE->_k == k)
                            {
                                break;
                            }
                            ++pE;
                        }

                        if(pE == a_Entries + sz_EntryCount)
                        {
                            return false;
                        }

                        //We don't need to swap if the entry is the only one in the bucket or if it is the last one.
                        entry* pLast = a_Entries + sz_EntryCount - 1;
                        if((sz_EntryCount > 1) && (pE != pLast))
                        {
                            pE = pLast;
                        }

                        a_Entries = static_cast<entry*>(realloc(a_Entries, sizeof(entry)*(--sz_EntryCount)));
                        if(a_Entries == NULL && sz_EntryCount > 0)
                        {
                            throw std::bad_alloc();
                        }

                        return true;
                    }

                    inline entry* find(const KEY& k) throw()
                    {
                        //Better implement a search policy.
                        entry* pE = a_Entries;
                        while(pE != a_Entries + sz_EntryCount)
                        {
                            if(pE->_k == k)
                            {
                                break;
                            }
                            ++pE;
                        }

                        if(pE == a_Entries + sz_EntryCount)
                        {
                            return NULL;
                        }

                        return pE;
                    }
                };

                HASH_FUNCTION& _hf;
                KEY_COMP _kc;

                size_t sz_TableSize;
                double d_MultFactor;                                            //Recalculate this as 1/sz_TableSize everytime sz_TableSize changes.
                size_t sz_NextResizeLimit;
                size_t sz_EntryCount;
                double d_ExpectedLoadFactor;
                double d_CurrentLoadFactor;

                //If the load factor is relatively high (say >0.5 assuming sizeof(entry) == 2*sizeof(size_t)), it is more space efficient to keep a straight bucket array. But if the load factor is low, memory consumption would be lower if a pointer array of Entries is used here. But, because we would not be much concerned with a little additional memory being used when there are few entries, I think array of bucket objects is better. Further, it bypasses a pointer lookup. May have to reconsider is a situation where multiple hash tables are used (Perhaps as an array).
                bucket* a_Buckets;

                hash_container(const hash_container&);
                hash_container& operator=(const hash_container&);

                inline void calculateMultFactor() throw()
                {
                    d_MultFactor = 1.0f/static_cast<double>(sz_TableSize + 1);
                    //sz_NextResizeLimit = static_cast<size_t>(d_ExpectedLoadFactor*sz_TableSize);
                    //Have a look at this.
                    //TODO
                }

                void resize(size_t szNewSize) throw(std::bad_alloc)
                {
                    if(szNewSize == 0)
                    {
                        szNewSize = 1;
                    }
                    size_t szOldSize = sz_TableSize;
                    for(size_t szI = szNewSize; szI < szOldSize; ++szI)
                    {
                        a_Buckets[szI].~bucket();
                    }

                    a_Buckets = static_cast<bucket*>(realloc(a_Buckets, sizeof(bucket)*szNewSize));
                    if(a_Buckets == NULL)
                    {
                        throw std::bad_alloc();
                    }
                    //Unnecessary at the moment. But, just in case that bucket changes.
                    for(size_t szI = szOldSize; szI < szNewSize; ++szI)
                    {
                         new (&a_Buckets[szI]) bucket();
                    }

                    sz_TableSize = szNewSize;
                    calculateMultFactor();
                }

                inline bucket* get_bucket(const KEY& k) throw()
                {
                    return a_Buckets + _hf(k, sz_TableSize);
                }

                inline bool need_resizing() const throw()
                {

                }
            public:
                //typedef iterator void*;
                //typedef const_iterator void*;

                //iterator Insert(KEY& k, VALUE& v);
                //VALUE& Find(Key& k);
                //const VALUE& Find(Key& k);
                //iterator Find(KEY k);
                //const_iterator Find(KEY k);
                //void Delete(KEY& k);
                //void Delete(iterator it);
                //void Delete(const_iterator it);
                class iterator
                {
                    private:
                        entry* p_Entry;
                        bucket* p_Bucket;

                        friend class bucket;

                    public:
                        iterator(entry* pEntry)
                            :p_Entry(pEntry)
                        {
                        }

                        iterator()
                        {
                            p_Entry = NULL;
                        }

                        iterator(const iterator& it)
                        {
                            this->p_Entry = it.p_Entry;
                        }

                        inline VALUE& operator*() const
                        {
                            return p_Entry->_v;
                        }

                        inline bool operator==(const iterator& it) const
                        {
                            return this->p_Entry == it.p_Entry;
                        }

                        inline bool operator!=(const iterator& it) const
                        {
                            return !(*this == it);
                        }

                        inline iterator& operator=(const iterator& it)
                        {
                            this->p_Entry = it.p_Entry;
                        }

                        inline VALUE* operator->() const
                        {
                            return &p_Entry->_v;
                        }

                        inline iterator operator++()
                        {
                            return *this;
                        }

                        inline iterator& operator++(int)
                        {
                            //WRONG!!!
                            //TODO : Change this.
                            return *this;
                        }
                };

            private:
                iterator _EndIt;

            public:
                hash_container(HASH_FUNCTION& hf, size_t szTableSize = 1024, double dLoadFactor = 0.7f, KEY_COMP kc = KEY_COMP())throw(std::bad_alloc)
                    :_hf(hf), sz_TableSize(szTableSize), d_ExpectedLoadFactor(dLoadFactor), _kc(kc)
                {
                    if(d_ExpectedLoadFactor < 0.1f)
                    {
                        d_ExpectedLoadFactor = 0.1f;
                    }

                    a_Buckets = NULL;
                    sz_TableSize = 0;
                    if(szTableSize == 0)
                    {
                        szTableSize = 1;
                    }
                    resize(szTableSize);
                    d_CurrentLoadFactor = 0.0f;
                    sz_EntryCount = 0;

                    _EndIt = iterator(NULL);
                }

                virtual ~hash_container()
                {
                    for(size_t szI = 0; szI < sz_TableSize; ++szI)
                    {
                        a_Buckets[szI].~bucket();
                    }
                }

                inline iterator find(const KEY& k) throw()
                {
                    bucket* pBucket = get_bucket(k);
                    return pBucket->find(k);
                }

                inline bool insert(const KEY& k, const VALUE& v) throw(std::bad_alloc)
                {
                    bucket* pBucket = get_bucket(k);
                    bool bRet = false;
                    try
                    {
                        bRet = pBucket->insert(k, v);
                    }
                    catch(std::bad_alloc& e)
                    {
                        //What now?
                        throw e;
                    }
                    if(bRet == true)
                    {
                        ++sz_EntryCount;
                    }
                    return bRet;
                }

                inline VALUE& operator[](const KEY& k) throw(std::bad_alloc)
                {
                    bucket* pBucket = get_bucket(k);

                }

                inline bool erase(const KEY& k) throw(std::bad_alloc)
                {
                    bucket* pBucket =  get_bucket(k);
                    bool bRet = false;
                    try
                    {
                        bRet = pBucket->erase(k);
                    }
                    catch(std::bad_alloc& e)
                    {
                        throw e;
                    }
                    if(bRet == true)
                    {
                        --sz_EntryCount;
                    }
                    return bRet;
                }

                inline iterator end() const
                {
                    return _EndIt;
                }

                inline size_t size() const
                {
                    return sz_EntryCount;
                }

                inline size_t table_size() const
                {
                    return sz_TableSize;
                }

                inline double current_load_factor() const
                {
                    return d_MultFactor*static_cast<double>(sz_EntryCount);
                }

                inline double expected_load_factor() const
                {
                    return d_ExpectedLoadFactor;
                }
        };
}

#endif

Body:
.1. operator-> should almost always return a pointer type.  When acting as an iterator with value_type T, it should return T*.

In some rarer cases, operator-> may return a different class type, which also has an operator-> member function.

.2. There are no technical requirements on what either form of operator++ must return, but the usual conventions make them act most like the built-in meanings.

class T {
public:
    // pre-increment
    T& operator++() { increment_me(); return *this; }
    // post-increment
    T operator++(int) { T copy(*this); increment_me(); return copy; }
    //...
};

The built-in meaning of the pre-increment expression ++x first increments the number and then returns an lvalue to the incremented number.  A return type of T& acts similarly.

The built-in meaning of the post-increment expression 'x++' increments the variable but returns an rvalue copy of the variable's previous value.  So most user-defined overloads return a copy of the original value (which can practically never be a reference).


问:
Getting asked twice to insert integer
I have some homework to do for the University, and since I'm a beginner I don't know how to code yet. So, there are 10 tests with the grade of each being between 0 and 10. I have to make sure that I don't get any negative number or a number greater than 10. while running the code I have to put 2 numbers in order to proceed to the next one, when, I clearly want just the one saved to A[i]. I hope you understand even though I can't even explain the problem. :)</p>

```<code>#include<stdio.h>

int main()
{
    int A[10];
    int i, j;
    for ( i = 1; i<11; i++)
    {
        printf("Enter %d grade \n", i);
        scanf("%d", &j);
        if (j<=10 && j>=0)
         A[i] = j;
        else
         printf("Enter a number between 0 and 10\n");
         scanf("%d", &j);
    }
}
</code>```

答:
Maybe this is what you are looking for. You should try this using do-while loop.</p>

```<code>#include<stdio.h>

int main()
{
    int A[10];
    int i, j;
    for ( i = 0; i<10; i++)
    {
        do{
            printf("Enter %d grade \n", i+1);
            scanf("%d", &A[i]);
        }while(A[i]<0 || A[i]>10);
    }
}
</code>```

ContentLicense: CC BY-SA 3.0

Title: Getting asked twice to insert integer

Body:
I have some homework to do for the University, and since I'm a beginner I don't know how to code yet. So, there are 10 tests with the grade of each being between 0 and 10. I have to make sure that I don't get any negative number or a number greater than 10. while running the code I have to put 2 numbers in order to proceed to the next one, when, I clearly want just the one saved to A[i]. I hope you understand even though I can't even explain the problem. :)

#include<stdio.h>

int main()
{
    int A[10];
    int i, j;
    for ( i = 1; i<11; i++)
    {
        printf("Enter %d grade \n", i);
        scanf("%d", &j);
        if (j<=10 && j>=0)
         A[i] = j;
        else
         printf("Enter a number between 0 and 10\n");
         scanf("%d", &j);
    }
}

Body:
Maybe this is what you are looking for. You should try this using do-while loop.

#include<stdio.h>

int main()
{
    int A[10];
    int i, j;
    for ( i = 0; i<10; i++)
    {
        do{
            printf("Enter %d grade \n", i+1);
            scanf("%d", &A[i]);
        }while(A[i]<0 || A[i]>10);
    }
}


问:
Conditionally insert different substring depending on column name
An example of mydataframe is this:

```<code>datatimedf = data.frame(time_start_1 = c('Apr 2005', '2004', '2000', 'Mar 2011'), time_end_1 = c('Apr 2012', '2011', 'Oct 2001', '2012'))
</code>```

Some values in these columns have year and month, others have only year.  If a cell has only the year (month is missing), I want to insert a month value.

The month value to insert depends on which column it is:  If it's in the time_start_1 column, insert "Jan" and if it is in the time_end_1 column insert "Dec".

Example of expected output:

```<code>datatimedf = data.frame(time_start_1 = c('Apr 2005', 'Jan 2004', 'Jan 2000', 'Mar 2011'), time_end_1 = c('Apr 2012', 'Dec 2011', 'Oct 2001', 'Dec 2012'))
</code>```

答:
If I got your intent right, this should work as long as you have character columns and not factors (hence the stringsAsFactors = F)

```<code>library(dplyr)
library(stringr)

        datatimedf = data.frame(time_start_1 = c('Apr 2005', '2004', '2000', 'Mar 2011'), time_end_1 = c('Apr 2012', '2011', 'Oct 2001', '2012'), stringsAsFactors = F)

       datatimedf %>%
               mutate(time_start_1 = ifelse(str_detect(time_start_1, "[[:alpha:]]"), time_start_1, paste0("Jan ", time_start_1)))  %>%
               mutate(time_end_1 = ifelse(str_detect(time_end_1, "[[:alpha:]]"), time_end_1, paste0("Dec ", time_end_1)))
</code>```

Body:
An example of mydataframe is this:

datatimedf = data.frame(time_start_1 = c('Apr 2005', '2004', '2000', 'Mar 2011'), time_end_1 = c('Apr 2012', '2011', 'Oct 2001', '2012'))

Some values in these columns have year and month, others have only year.  If a cell has only the year (month is missing), I want to insert a month value.

The month value to insert depends on which column it is:  If it's in the time_start_1 column, insert "Jan" and if it is in the time_end_1 column insert "Dec".

Example of expected output:

datatimedf = data.frame(time_start_1 = c('Apr 2005', 'Jan 2004', 'Jan 2000', 'Mar 2011'), time_end_1 = c('Apr 2012', 'Dec 2011', 'Oct 2001', 'Dec 2012'))

Body:
If I got your intent right, this should work as long as you have character columns and not factors (hence the stringsAsFactors = F)

library(dplyr)
library(stringr)

        datatimedf = data.frame(time_start_1 = c('Apr 2005', '2004', '2000', 'Mar 2011'), time_end_1 = c('Apr 2012', '2011', 'Oct 2001', '2012'), stringsAsFactors = F)

       datatimedf %>%
               mutate(time_start_1 = ifelse(str_detect(time_start_1, "[[:alpha:]]"), time_start_1, paste0("Jan ", time_start_1)))  %>%
               mutate(time_end_1 = ifelse(str_detect(time_end_1, "[[:alpha:]]"), time_end_1, paste0("Dec ", time_end_1)))


问:
Unable to dismiss keyboard with UITextField
I cannot get textFieldShouldEndEditing to call. I have re created the links in interface builder and tried, but nothing seems to work. Any idea why this would not be called?

Edit

I am implementing both -textFieldShouldEndEditing and -textFieldDidFinishEditing. Adding the delegate for the textField didnt help either. The code I am using below is not triggering the log messages.

```<code>-(BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    NSLog(@"Done editing...");
    [textField resignFirstResponder];
    return YES;
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    NSLog(@"Done editing...");
}
</code>```

答:
set the delegate to your TextField

In the interface Builder select your TextField, then press command + 2(Connections) and connect the delegate outled with the file's owner then save, and with that should work.

the delegate method are:

```<code>-(void)textFieldDidBeginEditing:(UITextField *)textField {

 }

-(void)textFieldDidEndEditing:(UITextField *)textField {

 }
</code>```

Hope this can help you.

Body:
I cannot get textFieldShouldEndEditing to call. I have re created the links in interface builder and tried, but nothing seems to work. Any idea why this would not be called?

Edit

I am implementing both -textFieldShouldEndEditing and -textFieldDidFinishEditing. Adding the delegate for the textField didnt help either. The code I am using below is not triggering the log messages.

-(BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    NSLog(@"Done editing...");
    [textField resignFirstResponder];
    return YES;
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    NSLog(@"Done editing...");
}

Body:
set the delegate to your TextField

In the interface Builder select your TextField, then press command + 2(Connections) and connect the delegate outled with the file's owner then save, and with that should work.

the delegate method are:

-(void)textFieldDidBeginEditing:(UITextField *)textField {

 }

-(void)textFieldDidEndEditing:(UITextField *)textField {

 }

Hope this can help you.


问:
How to recognize numbers in an image in Python?
I'm currently trying to write a bot to play tetris on tetrisfriends.com to practice machine-learning, but I've become stuck. I'm trying to find a way to read the players score from the game but Tesseract doesn't recognize the font/numbers and I don't think I can retrain Tesseract to recognize the numbers either because it isn't a full font being used, just numbers.

The image that I'm trying to read the numbers from is this:
https://imgur.com/a/OVwV5

When I use Tesseract I can get it to recognize other words on the page, just not the numbers which is the part I need.

Does anyone have a way to do this, either by retraining Tesseract, another method, or any other way?

答:
I'm not very familiar with Tesseract in particular, but it might not your best bet here. If the end goal was just to make a bot, you could probably pull the text directly from the app rather than worrying about OCR, but if you want to learn more about machine learning and you haven't done them already the MNIST and CIFAR-10 datasets are fantastic places to start.

Anyway! The image you're trying to test has very low contrast, and the font is heavily stylised. Looking at the website itself it looks like the characters are coloured yellow:

If you preprocessed your image so that yellow pixels are black and all others are white you would have a much cleaner source to work with e.g.:

If you want to push forward with Tesseract for this and the preprocessing isn't enough then you will probably have to retrain it for this font. You will need to prepare a corpus, process it similarly to how you expect your source data to look, and then use something like qt-box-editor to correct the data. This guide should be able to walk you through the basic steps of retraining.


问:
Match list of substrings and strings and return substring if it matches
I've seen may questions on this topic but most are the opposite of mine. I have a list of strings (column of a data frame) and a list of sub strings. I want to compare each string to the list of sub strings If it contains a sub string then return that sub-string else print 'no match'.

```<code>    subs = [cat, dog, mouse]

    df

      Name       Number     SubMatch
     dogfood      1           dog
     catfood      3           cat
     dogfood      2           dog
     mousehouse   1           mouse
     birdseed     1           no match
</code>```

my current output looks like this though:

```<code>     Name       Number     SubMatch
     dogfood      1           dog
     catfood      3           dog
     dogfood      2           dog
     mousehouse   1           dog
     birdseed     1           dog
</code>```

I suspect my code is just returning the first thing in the series, how do I change that to the correct thing in the series? Here is the Function:

```<code>    def matchy(col, subs):
        for name in col:
            for s in subs:
                if any(s in name for s in subs):
                    return s
                else:
                    return 'No Match'
</code>```

答:
The pandaic way to solve this would be to not use loops at all. You could do this pretty simply with str.extract:

```<code>p = '({})'.format('|'.join(subs))
df['SubMatch'] = df.Name.str.extract(p, expand=False).fillna('no match')

df

         Name  Number  SubMatch
0     dogfood       1       dog
1     catfood       3       cat
2     dogfood       2       dog
3  mousehouse       1     mouse
4    birdseed       1  no match
</code>```

Body:
I've seen may questions on this topic but most are the opposite of mine. I have a list of strings (column of a data frame) and a list of sub strings. I want to compare each string to the list of sub strings If it contains a sub string then return that sub-string else print 'no match'.

    subs = [cat, dog, mouse]

    df

      Name       Number     SubMatch
     dogfood      1           dog
     catfood      3           cat
     dogfood      2           dog
     mousehouse   1           mouse
     birdseed     1           no match

my current output looks like this though:

     Name       Number     SubMatch
     dogfood      1           dog
     catfood      3           dog
     dogfood      2           dog
     mousehouse   1           dog
     birdseed     1           dog

I suspect my code is just returning the first thing in the series, how do I change that to the correct thing in the series? Here is the Function:

    def matchy(col, subs):
        for name in col:
            for s in subs:
                if any(s in name for s in subs):
                    return s
                else:
                    return 'No Match'

Body:
The pandaic way to solve this would be to not use loops at all. You could do this pretty simply with str.extract:

p = '({})'.format('|'.join(subs))
df['SubMatch'] = df.Name.str.extract(p, expand=False).fillna('no match')

df

         Name  Number  SubMatch
0     dogfood       1       dog
1     catfood       3       cat
2     dogfood       2       dog
3  mousehouse       1     mouse
4    birdseed       1  no match


问:
Incompatible types error with java
```<code>Lab7_5.java:79: error: incompatible types: possible lossy conversion from double to int
                extra = minutesOver + .20;
                                    ^
Lab7_5.java:83: error: incompatible types: possible lossy conversion from double to int
                return totalDue;
                       ^
2 errors
</code>```

I looked around on the website and it turns out other people also had this issue but I looked at the comments and I still don't understand the problem, there's no double in my code why would it say this. And I also don't understand the error saying cannot find symbol. Please help I've really been stuck on this for a while.

code:

```<code>import java.util.Scanner;

public class Lab7_5 {
    static Scanner keyboard = new Scanner(System.in);

    public static void main(String[] args) {
        // Declare local variables
        int minutesAllowed, minutesUsed, minutesOver;
        double totalDue;
        String endProgram = "no";

        // Loop to run program again
        while (endProgram.equals("no")) {
            minutesAllowed = 0;
            minutesUsed = 0;
            totalDue = 0;
            minutesOver = 0;

            // Call functions
            minutesAllowed = getAllowed(minutesAllowed);
            minutesUsed = getUsed(minutesUsed);
            minutesOver = minutesUsed - minutesAllowed;

        if (minutesOver < 0){
            minutesOver = 0;
    }
            totalDue = calcTotal(totalDue, minutesOver, minutesUsed, minutesAllowed);

            // Call functions cont.
            printData(minutesAllowed, minutesUsed, totalDue, minutesOver);

            System.out.println("Do you want to end the program (enter no to process another set of test scores): ");
            endProgram = keyboard.next();

        while (!(endProgram.equals("yes")) && !(endProgram.equals("no"))){
            System.out.println("Please enter a value of yes or no");
            endProgram = keyboard.nextLine();

        }
    }
    }
    public static int getAllowed(int minutesAllowed) {
        System.out.println("How many minutes are allowed: ");

        minutesAllowed = keyboard.nextInt();
    while (minutesAllowed <200 || minutesAllowed >800) {
        System.out.println("Please enter minutes between 200 and 800 ");
        minutesAllowed = keyboard.nextInt();
    }

        return minutesAllowed;
    }

    public static int getUsed(int minutesUsed) {
        System.out.println ("How many minutes were used: ");
        minutesUsed = keyboard.nextInt();

        while (minutesUsed <0) {
            System.out.println("Please enter minutes of at least 0");
            System.out.println("How many minutes were used: ");
            minutesUsed = keyboard.nextInt();

        }
        return minutesUsed;
    }

    public static int calcTotal(double totalDue, int minutesOver, int minutesUsed, int minutesAllowed) {
        int extra;
    if (minutesUsed <= minutesAllowed){
        totalDue = 74.99;
    } else {
        minutesOver = minutesUsed - minutesAllowed;
        extra = minutesOver * .20;
        totalDue = 74.99 + extra;
        System.out.println ("You were over your minutes by" + minutesOver);
    }
        return totalDue;
    }

    public static void printData(int minutesAllowed, int minutesUsed, double totalDue, int minutesOver) {
        System.out.println("----------------MONTHLY USE REPORT----------------------");
        System.out.println("Minutes allowed were " + minutesAllowed);
        System.out.println("Minutes used were " + minutesUsed);
        System.out.println("Minutes over were " + minutesOver );
        System.out.println("Total due is $ " + totalDue);

    }
}
</code>```

答:
You declare extra as an int and then make it a double.

```<code>int extra;

extra = minutesOver * .20 // error here
// example 6 * .20 != an int
</code>```

Title: Incompatible types error with java

Body:
Lab7_5.java:79: error: incompatible types: possible lossy conversion from double to int
                extra = minutesOver + .20;
                                    ^
Lab7_5.java:83: error: incompatible types: possible lossy conversion from double to int
                return totalDue;
                       ^
2 errors

I looked around on the website and it turns out other people also had this issue but I looked at the comments and I still don't understand the problem, there's no double in my code why would it say this. And I also don't understand the error saying cannot find symbol. Please help I've really been stuck on this for a while.

code:

import java.util.Scanner;

public class Lab7_5 {
    static Scanner keyboard = new Scanner(System.in);

    public static void main(String[] args) {
        // Declare local variables
        int minutesAllowed, minutesUsed, minutesOver;
        double totalDue;
        String endProgram = "no";

        // Loop to run program again
        while (endProgram.equals("no")) {
            minutesAllowed = 0;
            minutesUsed = 0;
            totalDue = 0;
            minutesOver = 0;

            // Call functions
            minutesAllowed = getAllowed(minutesAllowed);
            minutesUsed = getUsed(minutesUsed);
            minutesOver = minutesUsed - minutesAllowed;

        if (minutesOver < 0){
            minutesOver = 0;
    }
            totalDue = calcTotal(totalDue, minutesOver, minutesUsed, minutesAllowed);

            // Call functions cont.
            printData(minutesAllowed, minutesUsed, totalDue, minutesOver);

            System.out.println("Do you want to end the program (enter no to process another set of test scores): ");
            endProgram = keyboard.next();

        while (!(endProgram.equals("yes")) && !(endProgram.equals("no"))){
            System.out.println("Please enter a value of yes or no");
            endProgram = keyboard.nextLine();

        }
    }
    }
    public static int getAllowed(int minutesAllowed) {
        System.out.println("How many minutes are allowed: ");

        minutesAllowed = keyboard.nextInt();
    while (minutesAllowed <200 || minutesAllowed >800) {
        System.out.println("Please enter minutes between 200 and 800 ");
        minutesAllowed = keyboard.nextInt();
    }

        return minutesAllowed;
    }

    public static int getUsed(int minutesUsed) {
        System.out.println ("How many minutes were used: ");
        minutesUsed = keyboard.nextInt();

        while (minutesUsed <0) {
            System.out.println("Please enter minutes of at least 0");
            System.out.println("How many minutes were used: ");
            minutesUsed = keyboard.nextInt();

        }
        return minutesUsed;
    }

    public static int calcTotal(double totalDue, int minutesOver, int minutesUsed, int minutesAllowed) {
        int extra;
    if (minutesUsed <= minutesAllowed){
        totalDue = 74.99;
    } else {
        minutesOver = minutesUsed - minutesAllowed;
        extra = minutesOver * .20;
        totalDue = 74.99 + extra;
        System.out.println ("You were over your minutes by" + minutesOver);
    }
        return totalDue;
    }

    public static void printData(int minutesAllowed, int minutesUsed, double totalDue, int minutesOver) {
        System.out.println("----------------MONTHLY USE REPORT----------------------");
        System.out.println("Minutes allowed were " + minutesAllowed);
        System.out.println("Minutes used were " + minutesUsed);
        System.out.println("Minutes over were " + minutesOver );
        System.out.println("Total due is $ " + totalDue);

    }
}

Body:
You declare extra as an int and then make it a double.

int extra;

extra = minutesOver * .20 // error here
// example 6 * .20 != an int


问:
DynamoDB Sort and select top 20 records
I wanted to get records like top 10 or 20 basically some configurable number which are sorted based on a date field stored as ISO-8601 format uuuu-MM-dd after applying some filters.

```<code>@DynamoDBTable(tableName = "Data")
@NoArgsConstructor
@ToString
public class Data {

    private LocalDate date;
    @Setter
    private Long number;
    @Setter
    private STATUS status;

    @DynamoDBHashKey
    @DynamoDBTypeConverted(converter = LocalDateConverter.class)
    public LocalDate getDate() {
        return date;
    }

    @DynamoDBTypeConverted(converter = LocalDateConverter.class)
    public void setDate(LocalDate date) {
        this.date = date;
    }

    @DynamoDBIndexHashKey(globalSecondaryIndexName = "idx_Data_number")
    public Long getCompetitionId() {
        return number;
    }

    @DynamoDBTypeConvertedEnum
    @DynamoDBIndexHashKey(globalSecondaryIndexName = "idx_Data_status")
    public STATUS getStatus() {
        return status;
    }
}
</code>```

I need to get say 20 records sorted based on date field after filtering based on number and multiple status. I was using ScanRequest to basically filter the records. Now I want to limit the results and get top records based on the date.

```<code>@AllArgsConstructor
public class DataRepositoryImpl implements DataRepository {
 private final DynamoDBMapper dynamoDBMapper;
 private final AmazonDynamoDB amazonDynamoDB;

 @Override
 public List<Data> findAll(Long number, List<String> status) {
    Condition numberCondition = new Condition()
            .withComparisonOperator(ComparisonOperator.EQ)
            .withAttributeValueList(new AttributeValue().withN(String.valueOf(number)));

    List<AttributeValue> attributeValues = newArrayList();
    status.forEach(s -> attributeValues.add(new AttributeValue().withS(s)));
    Condition statusCondition = new Condition()
            .withComparisonOperator(ComparisonOperator.IN)
            .withAttributeValueList(attributeValues);

    Map<String, Condition> conditions = newHashMap();
    conditions.put("number", numberCondition);
    conditions.put("status", statusCondition);

    ScanRequest scanRequest = new ScanRequest()
            .withTableName("Data")
            .withScanFilter(conditions)
            .withConditionalOperator(ConditionalOperator.AND);

    ScanResult scanResult = amazonDynamoDB.scan(scanRequest);
    return dynamoDBMapper.marshallIntoObjects(Data.class, scanResult.getItems());
    }
}
</code>```

答:
DynamoDB sorts the data only by SORT KEY attribute.

DynamoDB doesn't have a feature to sort the data by any attribute (i.e. any non-key attributes or partition key attribute) except sort key.

Partition key and sort key – Referred to as a composite primary key,
  this type of key is composed of two attributes. The first attribute is
  the partition key, and the second attribute is the sort key. DynamoDB
  uses the partition key value as input to an internal hash function.
  The output from the hash function determines the partition (physical
  storage internal to DynamoDB) in which the item will be stored. All
  items with the same partition key are stored together, in sorted order
  by sort key value.

DynamoDB stores the data in multiple partitions. Like RDBMS, it doesn't have any ORDER BY clause as well. However, it does have ScanIndexForward option which can be applied only for Sort key attribute.

ScanIndexForward — (Boolean) Specifies the order for index traversal:
  If true (default), the traversal is performed in ascending order; if
  false, the traversal is performed in descending order.

Title: DynamoDB Sort and select top 20 records

Body:
I wanted to get records like top 10 or 20 basically some configurable number which are sorted based on a date field stored as ISO-8601 format uuuu-MM-dd after applying some filters.

@DynamoDBTable(tableName = "Data")
@NoArgsConstructor
@ToString
public class Data {

    private LocalDate date;
    @Setter
    private Long number;
    @Setter
    private STATUS status;

    @DynamoDBHashKey
    @DynamoDBTypeConverted(converter = LocalDateConverter.class)
    public LocalDate getDate() {
        return date;
    }

    @DynamoDBTypeConverted(converter = LocalDateConverter.class)
    public void setDate(LocalDate date) {
        this.date = date;
    }

    @DynamoDBIndexHashKey(globalSecondaryIndexName = "idx_Data_number")
    public Long getCompetitionId() {
        return number;
    }

    @DynamoDBTypeConvertedEnum
    @DynamoDBIndexHashKey(globalSecondaryIndexName = "idx_Data_status")
    public STATUS getStatus() {
        return status;
    }
}

I need to get say 20 records sorted based on date field after filtering based on number and multiple status. I was using ScanRequest to basically filter the records. Now I want to limit the results and get top records based on the date.

@AllArgsConstructor
public class DataRepositoryImpl implements DataRepository {
 private final DynamoDBMapper dynamoDBMapper;
 private final AmazonDynamoDB amazonDynamoDB;

 @Override
 public List<Data> findAll(Long number, List<String> status) {
    Condition numberCondition = new Condition()
            .withComparisonOperator(ComparisonOperator.EQ)
            .withAttributeValueList(new AttributeValue().withN(String.valueOf(number)));

    List<AttributeValue> attributeValues = newArrayList();
    status.forEach(s -> attributeValues.add(new AttributeValue().withS(s)));
    Condition statusCondition = new Condition()
            .withComparisonOperator(ComparisonOperator.IN)
            .withAttributeValueList(attributeValues);

    Map<String, Condition> conditions = newHashMap();
    conditions.put("number", numberCondition);
    conditions.put("status", statusCondition);

    ScanRequest scanRequest = new ScanRequest()
            .withTableName("Data")
            .withScanFilter(conditions)
            .withConditionalOperator(ConditionalOperator.AND);

    ScanResult scanResult = amazonDynamoDB.scan(scanRequest);
    return dynamoDBMapper.marshallIntoObjects(Data.class, scanResult.getItems());
    }
}


问:
Interacting with multiple servers over SSH in PHP
I'm currently writing a deployment framework in PHP.  The framework connects to servers and executes commands over SSH.  I've been looking for quite a while trying to find a way in PHP to do this better.  Here are the requirements.  The technique should be able to:

Enter the SSH password programmatically.  I know that using SSH keys is the way to go when you want password-less SSH logons, but remember, this is a deployment framework.  It could potentially be deploying to 25 servers at a time.  It doesn't seem right to require the user to have set up SSH keys to use the framework, and who wants to enter their password 25 times?  I'm using Capistrano as a model here - it asks for your password once, then uses it to establish the SSH connections without re-prompting the user.  I'm not suggesting the passwords be stored in the deploy script, just (silently) entered once and used until the deploy tasks are finished.

Send output to the PHP script.  I would like to be able to intercept the terminal output from each of the SSH sessions independently, modify it, then send it back to the terminal for the user to see.  This way, I can prepend the name of the server onto each line of output to show what's going on.

Provide write (as well as read) access to the terminal.  It's important that the user (or the script) be able to enter other information into the terminal besides just the SSH password.

Support SSH v2.

Currently, my framework "compiles" the commands from the deploy script into one giant string and executes them by using the SSH command.  Each final deploy command looks something like this:

ssh -t -t -p 12345 user@server.com 'command1; command2;'

Each of these SSH commands is executed via PHP's built-in passthru function:

<?php passthru("ssh -t -t -p 12345 user@server.com 'command1; command2;'"); ?>

I have tried using proc_open and nearly all of PHP's other command-executing functions to no avail - none of them provide all the functionality I've listed above.  In addition, I've tried several pure PHP SSH implementations, also to no avail.  The libraries either don't supply write access to the terminal or don't support SSH v2.

Any help on this would be greatly appreciated - thanks in advance!

答:
Do you consider the following to be an example of write access to the terminal?:

```<code>ssh -t -t -p 12345 user@server.com 'command1; command2;'
</code>```

If so then you can do that with phpseclib's pure PHP SSH implementation.  eg.

```<code>$ssh = new Net_SSH2(...);
$ssh->login(..., ...);
$ssh->exec('command1; command2;');
</code>```

If not then (1) I'd say you'd be better off using phpseclib than you are with you're current implementation and (2) if you want what the phpseclib author has referred to as "interactive" support maybe you could try contacting the author?  Maybe offer to pay him some money to incentivize him to develop the feature.  Looking at the support forums the author seems responsive enough.

Body:
Do you consider the following to be an example of write access to the terminal?:

ssh -t -t -p 12345 user@server.com 'command1; command2;'

If so then you can do that with phpseclib's pure PHP SSH implementation.  eg.

$ssh = new Net_SSH2(...);
$ssh->login(..., ...);
$ssh->exec('command1; command2;');

If not then (1) I'd say you'd be better off using phpseclib than you are with you're current implementation and (2) if you want what the phpseclib author has referred to as "interactive" support maybe you could try contacting the author?  Maybe offer to pay him some money to incentivize him to develop the feature.  Looking at the support forums the author seems responsive enough.


答:
How about this:

```<code>def matchy(col, subs):
    for name in col:
        try:
            return next(x for x in subs if x in name)
        except StopIteration:
            return 'No Match'
</code>```

The problem with your code was that you were checking for matches with any but returning the first item of the iteration first (dog).

EDIT kudos @Coldspeed

```<code>def matchy(col, subs):
    for name in col:
        return next(x for x in subs if x in name, 'No match')
</code>```

Title: Match list of substrings and strings and return substring if it matches

Body:
How about this:

def matchy(col, subs):
    for name in col:
        try:
            return next(x for x in subs if x in name)
        except StopIteration:
            return 'No Match'

The problem with your code was that you were checking for matches with any but returning the first item of the iteration first (dog).

EDIT kudos @Coldspeed

def matchy(col, subs):
    for name in col:
        return next(x for x in subs if x in name, 'No match')


问:
Draw a polygon (preferably rectangle) on Custom Overlays (Microsoft.Maps.CustomOverlay) in Bing Maps v8
On Bing Maps v8 Is it possible to draw a Polygon (preferably rectangle) on Custom Overlay (Microsoft.Maps.CustomOverlay).

I have been able to render Images (as pushpins) on Custom Overlays using Canvas Layer example given in the link

https://bingmapsv8samples.azurewebsites.net/#Canvas%20Layer

I want to draw a rectangle on Top of this Canvas Layer.

答:
Polygon's are rendered within the base map canvas. As such changing the zIndex such that custom overlays are below polygons would result in the overlay being behind the base map and not visible. It is not possible to put custom overlays between the base map and polygons at this time.

That said, if you are using the drawing tools, it uses a separate canvas when drawing/editing which is above custom overlays. If you are simply drawing a polygon/rectangle and then doing a search with it, that would work, but the final polygon would end up behind the overlay as soon as you leave edit mode.

However, polygons should always be rendered behind pushpins This is standard practice in all mapping platforms.


问:
Cannot resolve symbol 'FirebaseAuth'
Why am I getting this error? My repository and Google play services are up to date and I've used all the requires steps for using Firebase like copying firebase code in both build.gradle(Project and app). The intellisence doesn't even show FirebaseAuth but displays other members of Firebase.</p>

答:
Solved the error by adding this to the build.gradle file(for app) -

```<code>compile 'com.google.firebase:firebase-auth:9.2.1'
compile "com.google.android.gms:play-services-gcm:9.2.1"
</code>```

Title: Cannot resolve symbol 'FirebaseAuth'

Body:
Solved the error by adding this to the build.gradle file(for app) -

compile 'com.google.firebase:firebase-auth:9.2.1'
compile "com.google.android.gms:play-services-gcm:9.2.1"

ContentLicense: CC BY-SA 4.0


问:
How can I use fake sendmail with SwiftMailer on Windows?
I wish to send emails using PHP on Windows via an external SMTP server.  I must use SwiftMailer for this purpose.

I can send emails via the external SMTP server using PHP's native mail() function and Fake Sendmail for Windows, but I cannot get SwiftMailer working.

Working Setup Using PHP's mail() Function

Here is the PHP code I use to send mail successfully using the native mail() function.

```<code>$returnValue = mail
(
   $params['to'     ],
   $params['subject'],
   $params['body'   ],
   "From: Sender McSender <{$params['from']}>"
);

echo "mail() returned "; var_dump($returnValue);
</code>```

Here is the relevant portion of my php.ini file.

```<code>[mail function]
sendmail_path = "C:\usr\lib\sendmail.exe"
</code>```

Fake Sendmail for Windows has its own sendmail.ini file, in which I have specified my smtp_server, smtp_port, auth_username, and auth_password.

When I run above PHP code by loading a page in my web browser, the output indicates that the mail() function returns true, and the email arrives at its intended destination as expected.

Attempted Setup Using SwiftMailer (Not Working)

Attempting to achieve the same result using SwiftMailer, I replace my PHP code above with the following, as instructed to in the SwiftMailer documentation.

```<code>$transport = Swift_SendmailTransport::newInstance('/usr/lib/sendmail -t');
$mailer    = Swift_Mailer::newInstance($transport);
$message   = Swift_Message::newInstance()
->setSubject($params['subject'])
->setFrom($params['from'])
->setTo($params['to'])
->setBody($params['body']);

$nSent = $mailer->send($message);

echo "Number of emails sent: $nSent\n";
</code>```

When I attempt to run the PHP code above by loading a page in my web browser, the page just loads forever.  I have traced the PHP code in the SwiftMailer library as far as I can, and found that I could not see output from echo statements after the "if ($err = stream_get_contents($pipes[2])) {" line below.  If I cut and paste the 'echo "Okay so far."' and 'die;' lines to after the 'if' condition, either inside or outside the curly braces following the 'if', the page just keeps loading forever.

```<code>/**
 * Opens a process for input/output.
 */
private function _establishProcessConnection()
{
echo "In StreamBuffer->_establishProcessConnection()\n";
    $command = $this->_params['command'];
    $descriptorSpec = array(
        0 => array('pipe', 'r'),
        1 => array('pipe', 'w'),
        2 => array('pipe', 'w')
        );
    $this->_stream = proc_open($command, $descriptorSpec, $pipes);
    stream_set_blocking($pipes[2], 0);
echo "Okay so far.\n";
die;
    if ($err = stream_get_contents($pipes[2])) {
        throw new Swift_TransportException(
            'Process could not be started [' . $err . ']'
            );
    }
    $this->_in =& $pipes[0];
    $this->_out =& $pipes[1];
}
</code>```

Things I have Tried Already

I have tried using -bs instead of -t in the /usr/lib/sendmail command passed to Swift_SendmailTransport::newInstance().  I have tried passing no parameter (ie. neither -bs nor -t) also.

I have tried passing the 'from' parameter the same way as I do in the call to PHP's native mail() function above.  When I did that, SwiftMailer complained that my 'from' address 'does not comply with RFC 2822'.

I have tried (thanks to Michael Sivolobov's suggestion below), replacing '/usr/lib/sendmail -t' with 'C:\usr\lib\sendmail -t', and with 'C:/usr/lib/sendmail -t'.  In both cases, the page just keeps loading forever.

I've tried passing no arguments to the Swift_SendmailTransport::newInstance() function in the hope that Swift would figure out the path to my sendmail.exe from my php.ini file.  Doing that resulted in the following error "Uncaught exception 'Swift_TransportException' with message 'Process could not be started [The system cannot find the path specified.]"  The exception was thrown from the code section reproduced above.  Passing '-t' and '-bs' had the same effect.

I'm all out of ideas.  Any helpful suggestions anyone can offer on how to get the SwiftMailer code working would be greatly appreciated.

答:
Assuming you have installed the fake sendmail into a local directory like:

```<code>C:\wamp64\bin\sendmail\sendmail.exe
</code>```

Edit your php.ini file like this:

```<code>sendmail_path = "C:\wamp64\bin\sendmail\sendmail.exe -t"
</code>```

Edit your sendmail.ini file like this:

```<code>smtp_server=localhost
smtp_port=25
smtp_ssl=none
</code>```

then use swiftmailer SMTP transport like this:

```<code>$transport = new Swift_SmtpTransport('localhost', 25);
</code>```

Swift_SendmailTransport is designed only for (Linux/UNIX) executable.

For Laravel Users

the process is the same but you also need to edit your .env file like this:

```<code>MAIL_DRIVER=smtp
MAIL_HOST=localhost
MAIL_PORT=25
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=
MAIL_FROM_ADDRESS=myemail@example.com
MAIL_FROM_NAME="My Name"
</code>```

Body:
I wish to send emails using PHP on Windows via an external SMTP server.  I must use SwiftMailer for this purpose.

I can send emails via the external SMTP server using PHP's native mail() function and Fake Sendmail for Windows, but I cannot get SwiftMailer working.

Working Setup Using PHP's mail() Function

Here is the PHP code I use to send mail successfully using the native mail() function.

$returnValue = mail
(
   $params['to'     ],
   $params['subject'],
   $params['body'   ],
   "From: Sender McSender <{$params['from']}>"
);

echo "mail() returned "; var_dump($returnValue);

Here is the relevant portion of my php.ini file.

[mail function]
sendmail_path = "C:\usr\lib\sendmail.exe"

Fake Sendmail for Windows has its own sendmail.ini file, in which I have specified my smtp_server, smtp_port, auth_username, and auth_password.

When I run above PHP code by loading a page in my web browser, the output indicates that the mail() function returns true, and the email arrives at its intended destination as expected.

Attempted Setup Using SwiftMailer (Not Working)

Attempting to achieve the same result using SwiftMailer, I replace my PHP code above with the following, as instructed to in the SwiftMailer documentation.

$transport = Swift_SendmailTransport::newInstance('/usr/lib/sendmail -t');
$mailer    = Swift_Mailer::newInstance($transport);
$message   = Swift_Message::newInstance()
->setSubject($params['subject'])
->setFrom($params['from'])
->setTo($params['to'])
->setBody($params['body']);

$nSent = $mailer->send($message);

echo "Number of emails sent: $nSent\n";

When I attempt to run the PHP code above by loading a page in my web browser, the page just loads forever.  I have traced the PHP code in the SwiftMailer library as far as I can, and found that I could not see output from echo statements after the "if ($err = stream_get_contents($pipes[2])) {" line below.  If I cut and paste the 'echo "Okay so far."' and 'die;' lines to after the 'if' condition, either inside or outside the curly braces following the 'if', the page just keeps loading forever.

/**
 * Opens a process for input/output.
 */
private function _establishProcessConnection()
{
echo "In StreamBuffer->_establishProcessConnection()\n";
    $command = $this->_params['command'];
    $descriptorSpec = array(
        0 => array('pipe', 'r'),
        1 => array('pipe', 'w'),
        2 => array('pipe', 'w')
        );
    $this->_stream = proc_open($command, $descriptorSpec, $pipes);
    stream_set_blocking($pipes[2], 0);
echo "Okay so far.\n";
die;
    if ($err = stream_get_contents($pipes[2])) {
        throw new Swift_TransportException(
            'Process could not be started [' . $err . ']'
            );
    }
    $this->_in =& $pipes[0];
    $this->_out =& $pipes[1];
}

Things I have Tried Already

I have tried using -bs instead of -t in the /usr/lib/sendmail command passed to Swift_SendmailTransport::newInstance().  I have tried passing no parameter (ie. neither -bs nor -t) also.

I have tried passing the 'from' parameter the same way as I do in the call to PHP's native mail() function above.  When I did that, SwiftMailer complained that my 'from' address 'does not comply with RFC 2822'.

I have tried (thanks to Michael Sivolobov's suggestion below), replacing '/usr/lib/sendmail -t' with 'C:\usr\lib\sendmail -t', and with 'C:/usr/lib/sendmail -t'.  In both cases, the page just keeps loading forever.

I've tried passing no arguments to the Swift_SendmailTransport::newInstance() function in the hope that Swift would figure out the path to my sendmail.exe from my php.ini file.  Doing that resulted in the following error "Uncaught exception 'Swift_TransportException' with message 'Process could not be started [The system cannot find the path specified.]"  The exception was thrown from the code section reproduced above.  Passing '-t' and '-bs' had the same effect.

I'm all out of ideas.  Any helpful suggestions anyone can offer on how to get the SwiftMailer code working would be greatly appreciated.

Body:
Assuming you have installed the fake sendmail into a local directory like:

C:\wamp64\bin\sendmail\sendmail.exe

Edit your php.ini file like this:

sendmail_path = "C:\wamp64\bin\sendmail\sendmail.exe -t"

Edit your sendmail.ini file like this:

smtp_server=localhost
smtp_port=25
smtp_ssl=none

then use swiftmailer SMTP transport like this:

$transport = new Swift_SmtpTransport('localhost', 25);

Swift_SendmailTransport is designed only for (Linux/UNIX) executable.

For Laravel Users

the process is the same but you also need to edit your .env file like this:

MAIL_DRIVER=smtp
MAIL_HOST=localhost
MAIL_PORT=25
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=
MAIL_FROM_ADDRESS=myemail@example.com
MAIL_FROM_NAME="My Name"


答:
Look closely here:

```<code>    if (j<=10 && j>=0)
     A[i] = j;
    else
     printf("Enter a number between 0 and 10\n");
     scanf("%d", &j);
</code>```

There are no braces around the else clause, so only the first statement after the  else applies to it.  The above is the same as:

```<code>    if (j<=10 && j>=0) {
     A[i] = j;
    } else {
     printf("Enter a number between 0 and 10\n");
    }
    scanf("%d", &j);
</code>```

So the second scanf is being executed every time.

Always put braces around if/else, for, and while blocks:

```<code>    if (j<=10 && j>=0) {
       A[i] = j;
    } else {
       printf("Enter a number between 0 and 10\n");
       scanf("%d", &j);
    }
</code>```

Also, your array int A[10]; has a total of 10 elements with indexes ranging from 0 to 9.  Your for loop uses indexes from 1 to 10, so you end up writing past the end of the array.  Fix this to use the proper indexes:

```<code>for ( i = 0; i<10; i++)
</code>```

Title: Getting asked twice to insert integer

Body:
Look closely here:

    if (j<=10 && j>=0)
     A[i] = j;
    else
     printf("Enter a number between 0 and 10\n");
     scanf("%d", &j);

There are no braces around the else clause, so only the first statement after the  else applies to it.  The above is the same as:

    if (j<=10 && j>=0) {
     A[i] = j;
    } else {
     printf("Enter a number between 0 and 10\n");
    }
    scanf("%d", &j);

So the second scanf is being executed every time.

Always put braces around if/else, for, and while blocks:

    if (j<=10 && j>=0) {
       A[i] = j;
    } else {
       printf("Enter a number between 0 and 10\n");
       scanf("%d", &j);
    }

Also, your array int A[10]; has a total of 10 elements with indexes ranging from 0 to 9.  Your for loop uses indexes from 1 to 10, so you end up writing past the end of the array.  Fix this to use the proper indexes:

for ( i = 0; i<10; i++)


问:
Send ArrayList<Float> between Activities
I have to draw a graph from the values stored in an ArrayList named "subZ" (It has 252 elements). In my main activity I store the values and then in the next activity I have to draw.

So I send it like this:

```<code>Intent change_screen = new Intent(MeasureScreenActivity.this, ResultScreenActivity.class);
//Send variables to another activity
change_screen.putExtra("standard_measurement",standard_measurement);
change_screen.putExtra("current_measurement",current_measurement);
change_screen.putExtra("subZ", subZ);
startActivity(change_screen);
//Effect of transition
overridePendingTransition(R.anim.fade_in,R.anim.fade_out);
finish();
</code>```

And in the other activity I recieve it like this:

```<code>//Store the data passed from MeasureScreenActivity
Intent intent = getIntent();
Bundle bundle = intent.getExtras();

//Make sure that bundle is not null
if(bundle != null) {
    standard_measurement = (String) bundle.get("standard_measurement");
    current_measurement = (int) bundle.get("current_measurement");
    subZ = (ArrayList<Float>) bundle.get("subZ");
}
</code>```

My question is: Is well done in this way? Because the metod putExtra(String, ArrayList) does not exist really.

I know about other way that is cast the ArrayList to array:

```<code>Float aux[] = subZ.toArray();
</code>```

And use the method putExtra(String, Float[]) to send in the same way than before.

I do not know which on in the best way to do this because I do not want to saturate the main thread.

Other way that I am thinking is to draw in the main activity and then send the draw to the next activity to show it. But I do not know if it is possible.

Which one of this three options will saturate less the main thread?

答:
Sergio, the answer is putParcelableArrayListExtra()

But there is something new in Android part of Architecture components. use LiveData https://developer.android.com/topic/libraries/architecture/livedata.html to keep you array in the ViewModel which can be shared through your activities.

Body:
I have to draw a graph from the values stored in an ArrayList named "subZ" (It has 252 elements). In my main activity I store the values and then in the next activity I have to draw.

So I send it like this:

Intent change_screen = new Intent(MeasureScreenActivity.this, ResultScreenActivity.class);
//Send variables to another activity
change_screen.putExtra("standard_measurement",standard_measurement);
change_screen.putExtra("current_measurement",current_measurement);
change_screen.putExtra("subZ", subZ);
startActivity(change_screen);
//Effect of transition
overridePendingTransition(R.anim.fade_in,R.anim.fade_out);
finish();

And in the other activity I recieve it like this:

//Store the data passed from MeasureScreenActivity
Intent intent = getIntent();
Bundle bundle = intent.getExtras();

//Make sure that bundle is not null
if(bundle != null) {
    standard_measurement = (String) bundle.get("standard_measurement");
    current_measurement = (int) bundle.get("current_measurement");
    subZ = (ArrayList<Float>) bundle.get("subZ");
}

My question is: Is well done in this way? Because the metod putExtra(String, ArrayList) does not exist really.

I know about other way that is cast the ArrayList to array:

Float aux[] = subZ.toArray();

And use the method putExtra(String, Float[]) to send in the same way than before.

I do not know which on in the best way to do this because I do not want to saturate the main thread.

Other way that I am thinking is to draw in the main activity and then send the draw to the next activity to show it. But I do not know if it is possible.

Which one of this three options will saturate less the main thread?


问:
Syntax for Templated Member Functions
Consider the following code:

```<code>template <typename Datatype>
class MyClass
{
    void doStuff();

    template <typename AnotherDatatype>
    void doTemplateStuff(AnotherDatatype Argument);
};

template <typename Datatype>
void MyClass<Datatype>::doStuff()
{
    // ...
}

template <typename Datatype>
template <typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
    // ...
}
</code>```

The implementation for the second member function, doTemplateStuff, will not compile if I condense it like this:

```<code>template <typename Datatype, typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
    // ...
}
</code>```

Why is this?  Shouldn't separating template information by commas have the same effect as putting each typename on its own line?  Or is there some subtle difference I'm not aware of...?

(Also, if someone can think of a better title please let me know.)

答:
This is an excellent question.  I don't know the specific reason that the standards committee decided to design templates this way, but I think it's a callback to lambda calculus and type theory.  Mathematically speaking, there is an isomorphism between any function that takes two arguments and returns a value and a function that takes in a single argument, then returns a function that takes in yet another argument and then returns a value.  For example:

λx. λy. x + y

is isomorphic with (but not identical to)

λ(x, y).  x + y

where (x, y) is a single object representing the pair of x and y.

With C++ member function templates, C++ chose to use the first of these systems.  You have to specify all the arguments for the outermost function, then, separately, all of the arguments for the innermost function.  Mathematically this is equivalent to specifying all of the arguments at the same time in one argument list, but C++ didn't choose to do this.

Now, a really good question is why they didn't do this.  I'm not fully sure of the rationale, but if I had to guess it's because of weird interactions with template specialization.  If I can think of something specific I'll update this post.

Title: Syntax for Templated Member Functions

Body:
Consider the following code:

template <typename Datatype>
class MyClass
{
    void doStuff();

    template <typename AnotherDatatype>
    void doTemplateStuff(AnotherDatatype Argument);
};

template <typename Datatype>
void MyClass<Datatype>::doStuff()
{
    // ...
}

template <typename Datatype>
template <typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
    // ...
}

The implementation for the second member function, doTemplateStuff, will not compile if I condense it like this:

template <typename Datatype, typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
    // ...
}

Why is this?  Shouldn't separating template information by commas have the same effect as putting each typename on its own line?  Or is there some subtle difference I'm not aware of...?

(Also, if someone can think of a better title please let me know.)


问:
rake db:migrate - PG:: InvalidSchamaName ERROR: no schema has been selected to create in
I am attempting to run a rake:db migrate on a postgres database for my rails application. rake:db drop (the db already existed I am fixing a bug that requires I recreate the db) runs fine rake:db create runs fine but when I run rake:db migrate I get the following error

ERROR --: PG::InvalidSchemaName: ERROR: no schema has been selected to create in.

My database.yml file looks fine (it was working so I'm not sure what happened?)

```<code>development:
adapter: postgressql
encoding: utf8
username: [myusername]
password: [mypassword]
host: [myhost]
port: 5432
database: myapp_dev
schema_search_path: "myapp_dev"
pool: 5
timeout: 5000
</code>```

Any idea what is going on?

答: For some reason there was no "myapp_dev" schema in my database, when I created it using the PGAdmin tool it fixed the issue.</p>

Body:
I am attempting to run a rake:db migrate on a postgres database for my rails application. rake:db drop (the db already existed I am fixing a bug that requires I recreate the db) runs fine rake:db create runs fine but when I run rake:db migrate I get the following error

ERROR --: PG::InvalidSchemaName: ERROR: no schema has been selected to create in.

My database.yml file looks fine (it was working so I'm not sure what happened?)

development:
adapter: postgressql
encoding: utf8
username: [myusername]
password: [mypassword]
host: [myhost]
port: 5432
database: myapp_dev
schema_search_path: "myapp_dev"
pool: 5
timeout: 5000

Any idea what is going on?


问:
.(dot) access to static method
Following is a popular code:

```<code>class A
{
public:
    static const string TYPE = "AEvent";
    const string& getType() { return TYPE; }
};
</code>```

Above code could be use like this:

```<code>if (aInstance.getType() == A::TYPE)
{
    ...
}
</code>```

It's fine. But it's not intuitiveness. Did not? Look at the next code:

```<code>class A
{
public:
    static const string& getType()
    {
        static const string TYPE = "AEvent";
        return TYPE;
    }
}
//Usage
if (aInstance.getType() == A::getType())
    ....
</code>```

Of course, getType is static method but it's possible to access dot operator and It's more intuitively see to me.

How do you think about?

答: As long as you're returning a static variable from static method it should be fine. It doesn't matter if you call it using dot or resolution operator. Either way it's part of the object as well as the class which should give you the same static variable.

Title: .(dot) access to static method

Body:
Following is a popular code:

class A
{
public:
    static const string TYPE = "AEvent";
    const string& getType() { return TYPE; }
};

Above code could be use like this:

if (aInstance.getType() == A::TYPE)
{
    ...
}

It's fine. But it's not intuitiveness. Did not? Look at the next code:

class A
{
public:
    static const string& getType()
    {
        static const string TYPE = "AEvent";
        return TYPE;
    }
}
//Usage
if (aInstance.getType() == A::getType())
    ....

Of course, getType is static method but it's possible to access dot operator and It's more intuitively see to me.

How do you think about?


问:
Select query using key firebase admin node js
I've a table like this in firebase:

```<code>thread_users{
  thread_id{
    user_id{
      //user details
    }
  }
}
</code>```

thread_users should have multiple thread_ids and each thread_id has multiple users.

I only have the user_id of a user. I need to query using this user_id to find  thread_ids of the user has belonged.

I haven't found any good solution for this requirement. Kindly help me to do this :)

答:
You will have to save your user_id to thread_id mappings separately. This will denormalize some of the data, but this is perfectly normal and even recommended when working with the Firebase realtime database.

Alternatively you can look into Cloud Firestore for Firebase. There you should be able to create a document per thread_id, and have a subcollection of users in each document.

Body:
I've a table like this in firebase:

thread_users{
  thread_id{
    user_id{
      //user details
    }
  }
}

thread_users should have multiple thread_ids and each thread_id has multiple users.

I only have the user_id of a user. I need to query using this user_id to find  thread_ids of the user has belonged.

I haven't found any good solution for this requirement. Kindly help me to do this :)