/******************************************************************************
Online C++ Compiler.
Code, Compile, Run and Debug C++ program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <iostream>
using namespace std;
// Determine whether a call is compile-time or runtime
// by erroring-out if the call was attempted as runtime
// ------------------------------------------------------------
// Modified from https://stackoverflow.com/a/40410624/12854372
// ------------------------------------------------------------
// In a constexpr context, there is no way to modify s, so
// ContextIsConstexpr()() always simply sets ignore = 1 successfully.
// In a non-constexpr context, the compiler needs to define operator()
// such that if s was manually modified, operator() could return no_symbol,
// so the linker must have access to no_symbol, which it does not.
extern bool no_symbol;
struct ContextIsConstexpr {
size_t s;
constexpr ContextIsConstexpr() : s(1) {}
constexpr void operator()() {
auto ignore = s ? 1 : no_symbol;
}
};
constexpr bool tryIgnoringResult()
{
ContextIsConstexpr()();
return true;
}
constexpr void thereIsNoResult() {
ContextIsConstexpr()();
}
int main()
{
constexpr auto result1 = tryIgnoringResult(); // OK, compile-time
auto result2 = tryIgnoringResult(); // OK, compile-time
// tryIgnoringResult(); // Unexpected, runtime!
// thereIsNoResult(); // Unexpected, runtime!
}