Residue<7> is a field: every non-zero element has an inverse, division works. Residue<6> is not: 2 has no inverse modulo 6, and the Fermat formula in the code just produces a wrong number. Nobody checks this at runtime — the wrong answer goes straight into the calculation. The compiler can refuse such code before it ever runs: a member function of a class template is only instantiated when it is actually called.
In the ring Residue<N>, division is mathematically defined only when N is prime. Right now operator/ compiles for ANY N and silently returns garbage for composite moduli. Make division a compile error for composite N — while +, -, * keep working for every N.
Residue<6> (or any composite N): +, -, * compile and workResidue<6>: calling / must NOT compileResidue<7> (or any prime N): / compiles and is correctstatic_assert with the provided isPrime, or SFINAE) — no runtime checks, no exceptionsMembers of a class template are instantiated lazily: Residue<6> with +, -, * is fine as long as nobody CALLS operator/. Put the check inside the member.
static_assert(isPrime(N), "...") inside operator/ fires only when that operator is instantiated — exactly the behaviour you want.
Hit Submit (or ⌘/Ctrl + ↵) — test results will show up here.