Reputation: 25
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) {
}
}
Upvotes: 0
Views: 181
Reputation: 385
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
Upvotes: 0