简体   繁体   中英

Error while compiling code having | operator overloaded under template definition ,with VS2017 Update8.2

My question is that while compiling C++ source code with Visual Studio 2017 Update 8.2, I am facing compilation error with message saying:

sstream(270): error C2131: expression did not evaluate to a constant

sstream(270): note: failure was caused by call of undefined function or one not declared 'constexpr'

sstream(270): note: see usage of 'operator |'

sstream(249): note: while compiling class template member function 'std::fpos<_Mbstatet> std::basic_stringbuf,std::allocator>::seekoff(__int64,std::ios_base::seekdir,std::ios_base::openmode)'

sstream(730): note: see reference to class template instantiation'std::basic_stringbuf,std::allocator>' being compiled

test.cpp(3): note: see reference to class template instantiation 'std::basic_stringstream,std::allocator>' being compiled

I am sharing the code snippet which can produce same compilation error. Please someone help me with this.

The answer given was good and solved few issues . however I am facing another issue . I put the overloaded template into a namespace but put that in header file , because the existing code has the overloaded template in a header file . Again I am facing same issue . I am updating the code now

My Code:
cpp file test.cpp

#include "test.hpp"
#include <sstream>
namespace testing 
{
struct Message {
    std::stringstream ss_;
};
} 

using namespace ABC;
int main() {
return 0;
}

header file test.hpp

namespace ABC 
{

template <typename T>

bool operator|(T v1, T v2) {
}
}

Defining global function templates for overloading operators is truly dangerous, because it will affect existing code within the same scope that uses the operators your have overloaded.

The error in your sample is because MSVC tries to compile

constexpr auto _Both = ios_base::in | ios_base::out;

with your operator | , and (un)fortunately, your overload function is not a constexpr-function.

The solution is simple: put your overloaded template into a namespace:

namespace ext_ops {

// operator to combine two parameter attributes v1 and v2, e.g.,
template <typename T>
bool operator|(T v1, T v2) {
    return false;
}

}

Aside: maybe you could check out how the STL had done that via: https://en.cppreference.com/w/cpp/utility/rel_ops/operator_cmp

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM