Consider the following code example, a simple template class wrapper with basic overloaded arithmetic operators. In this class’s operator/
I’m using the ternary operator to throw an exception if division by 0 is detected otherwise, I’m returning the calcuation.
some.h
#pragma once
#include <cassert>
#include <stdexcept>
template<typename T>
struct Var {
T var;
// ... other operators
const auto operator/(const Var& rhs) {
return ((rhs.var == 0) ? throw std::exception("Division by 0") : (var / rhs.var));
}
};
Here’s the driver program:
#include <iostream>
#include "some.h"
int main() {
try {
Var<int> t1{ 4 };
Var<int> t2{ 0 };
auto t3 = t1 / t2;
std::cout << t3 << 'n';
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
} catch (...) {
std::cerr << "Unknown Exceptionn";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
And this will compile and build and when we run it (I’m using Visual Studio), it will throw an exception giving this message to the console
Division by 0
C:Users...sourcereposData Structure Samplesx64DebugData Structure Samples.exe (process 8756) exited with cod
e 1.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the conso
le when debugging stops.
Press any key to close this window . . .
Okay, this is simple enough and it works.
Let’s say that I want to refactor this code with two primary objectives:
- First, Abstract the Operators away from the class
- Don’t want to throw an exception, but would rather assert at compile time.
The class would transform into this:
some.h
#pragma once
#include <cassert>
#include <stdexcept>
template<typename T>
struct Var {
T var;
};
// ... other operators
template<typename T>
const auto operator/(const Var<T>& lhs, const Var<T>& rhs) {
static_assert(rhs.var != 0, "Division by 0!");
return (lhs.var / rhs.var);
}
However, this is failing to compile with these generated errors…
1>------ Build started: Project: Data Structure Samples, Configuration: Debug x64 ------
1>main.cpp
1>c:users...sourcereposdata structure samplesdata structure samplesdatastructs.h(25): error C2131: expression did not evaluate to a constant
1>c:users...sourcereposdata structure samplesdata structure samplesdatastructs.h(25): note: failure was caused by a read of a variable outside its lifetime
1>c:users...sourcereposdata structure samplesdata structure samplesdatastructs.h(25): note: see usage of 'rhs'
1>c:users...sourcereposdata structure samplesdata structure samplesmain.cpp(15): note: see reference to function template instantiation 'const auto operator /<int>(const Var<int> &,const Var<int> &)' being compiled
1>Done building project "Data Structure Samples.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I can easily enough use assert
at runtime without any problems, however, I’m struggling to figure out how to use static_assert
properly within this context. What am I doing wrong, what am I missing here? I’ve searched online for various use case examples of static_assert
but haven’t found anything suitable. Even if I move the operators back inside of the class and try to use static_assert
I still end up with very similar error messages.
Source: Windows Questions C++