VS2012 VS Nov CTP: Completely different error message - by svenschmidt75

Status : 


Sign in
to vote
ID 790264 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 6/16/2013 7:19:04 AM
Access Restriction Public


Attached are two identical C++ projects: One uses the VS2012 compiler, the other the Noc CTP one.
Compiling Minres.cpp yields two different error messages, the CTP one is completely wrong.
Sign in to post a comment.
Posted by svenschmidt75 on 6/27/2013 at 6:44 PM
Ah, I see. Thanks for the explanation.

>In general, it is very dangerous to have a global operator template which can accept anything. It can beat other >overload unexpectedly.

Agreed. Trying to avoid stamping out all the operator+ combinations explicitly, I tried to work around that by using SFINAE but had too many compiler problems (bug reports submitted).

Thanks again,
Posted by Microsoft on 6/27/2013 at 5:30 PM
    Thanks for reporting the issue.
    This is by design. And it is related to our STL implementation which is simplified as follows:

template<typename T1, typename T2>
void operator+(T1, T2);

template<typename T>
struct iterator {
    iterator operator+(int) const;

template<typename T>
struct vector {
    void erase(iterator<T>) {}
    void resize() {
        iterator<T> t;
        erase(t + 0u);

int main()
    vector<int> s;

Note that 'iterator::operator+' expects 'int' while the argument is '0u' which has type 'unsigned int'.
So your global operator+ template is better and chosen.

In general, it is very dangerous to have a global operator template which can accept anything. It can beat other overload unexpectedly.
Posted by Microsoft on 6/17/2013 at 12:52 AM
Thank you for submitting feedback on Visual Studio and .NET Framework. Your issue has been routed to the appropriate VS development team for investigation. We will contact you if we require any additional information.
Posted by svenschmidt75 on 6/16/2013 at 1:02 PM
I realize that the attached project is probably difficult to work with, hence this minimal
example. What happens is this:

- there is a operator+ defined in the global namespace
- calling q.resize(4) ends up here:

    void resize(size_type _Newsize)
        {    // determine new length, padding as needed
        if (_Newsize < size())
            erase(begin() + _Newsize, end());
        else if (size() < _Newsize)

The problem seems to be happening on line
erase(begin() + _Newsize, end());
in expression
begin() + _Newsize
where the compiler seems to find the above global operator+.

Now, I am not a crack when it comes to name lookup rules, but should the compiler see operator+?
Not sure, but on http://gcc.godbolt.org/, gcc 4.8 compiles fine and generates code.

#include <type_traits>
#include <vector>

class Vector {

template<typename VECTOR_EXPR1, typename VECTOR_EXPR2, typename BINOP>
class VectorBinaryExpr {
    VectorBinaryExpr(VECTOR_EXPR1 const & lhs, VECTOR_EXPR2 const & rhs) {}

template<typename T1, typename T2>
typename VectorBinaryExpr<T1, T2, double>
operator+(T1 lhs, T2 rhs) {
    return VectorBinaryExpr<T1, T2, double>(lhs, rhs);

int main(int argc, char* argv[])
    std::vector<Vector> q;
    return 0;

Posted by Microsoft on 6/16/2013 at 7:51 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)