/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, PHP, Ruby,
C#, VB, Perl, Swift, Prolog, Javascript, Pascal, HTML, CSS, JS
Code, Compile, Run and Debug online from anywhere in world.
*******************************************************************************/
#include <stdio.h>
constexpr int CONST = 1;
template<int>
using Void = void;
template<typename PoisonDelayer>
constexpr auto procurePoison(int i) {
struct Poison {
// error: use of parameter from containing function
// constexpr auto operator()() const -> Void<(PoisonDelayer::delayStatic(i), 0)> {}
// error: use of parameter from containing function
// static constexpr auto drink() -> Void<(PoisonDelayer::delayStatic(i), 0)> {}
} poison;
return poison;
}
template<typename PoisonDelayer>
constexpr auto procurePoisonFromObject(PoisonDelayer poisonDelayer, int i) {
struct Poison {
// error: use of parameter from containing function
// constexpr auto operator()() const -> Void<(poisonDelayer(i), 0)> {}
// error: use of parameter from containing function
// static constexpr auto drink() -> Void<(poisonDelayer(i), 0)> {}
} poison;
return poison;
}
template<typename PoisonDelayer>
struct PoisonOuterTemplate {
const int& _i;
// Internal compiler error / use of this in a constant expr
// auto operator()() const -> Void<(PoisonDelayer::delayStatic(_i), 0)> {}
};
template<typename PoisonDelayer>
struct PoisonOuterTemplateStatic {
static const int& _i;
// error: the value of ‘PoisonOuterTemplateStatic::_i’ is not usable in a constant expression
// static auto drink() const -> Void<(PoisonDelayer::delayStatic(_i), 0)> {}
};
template<typename PoisonDelayer>
const int& PoisonOuterTemplateStatic<PoisonDelayer>::_i = CONST;
struct PoisonInnerTemplate {
const int& _i;
// Internal compiler error / use of this in a constexpr
template<typename PoisonDelayer>
auto drink() const -> Void<(PoisonDelayer::delayStatic(_i), 0)> {}
};
struct PoisonInnerTemplateStatic {
static const int& _i;
// error: the value of ‘PoisonInnerTemplateStatic::_i’ is not usable in a constant expression
// template<typename PoisonDelayer>
// static auto drink() -> Void<(PoisonDelayer::delayStatic(_i), 0)> {}
};
const int& PoisonInnerTemplateStatic::_i = CONST;
template<typename PoisonDelayer>
constexpr auto procurePoisonLambdaOuter(int i) {
// error: use of parameter from containing function
// auto lambda = []() -> Void<(PoisonDelayer::delayStatic(i), 0)> {};
// return lambda;
return 0;
}
struct PoisonLambdaInner {
static const int& _i;
// error: the value of ‘PoisonLambdaInner::_i’ is not usable in a constant expression
// template<typename PoisonDelayer>
// static auto lambda = []() -> Void<(PoisonDelayer::delayStatic(_i), 0)> {};
};
const int& PoisonLambdaInner::_i = CONST;
// error: use of parameter from containing function / i is not a constexpr
constexpr auto poisonLambda = [](auto poisonDelayer, int i) { return []() -> Void<poisonDelayer(i)> {}; };
struct Delayer {
static constexpr auto delayStatic(int input) { return input; }
constexpr auto operator()(int input) { return input; }
};
int main()
{
auto procurePoisonRes = procurePoison<Delayer>(1);
auto procurePoisonFromObjectRes = procurePoisonFromObject(Delayer{}, 1);
auto poisonOuterTemplate = PoisonOuterTemplate<Delayer>{CONST};
auto poisonOuterTemplateStatic = PoisonOuterTemplateStatic<Delayer>{};
auto poisonInnerTemplate = PoisonInnerTemplate{CONST};
auto poisonInnerTemplateStatic = PoisonInnerTemplateStatic{};
auto procurePoisonLambdaOuterRes = procurePoisonLambdaOuter<Delayer>(1);
auto poisonLambdaInner = PoisonLambdaInner{};
// auto poisonLambdaRes = poisonLambda(Delayer{}, 1);
return 0;
}