What follows is a simplified version of a tentative implementation for a template-based set, named TemplateArgs. For the sake of clarity and focus on the question at hand, TemplateArgs was converted into a non-parameterized class, and its size and elements are hard-coded. It should be C++11-compliant and portable (any OS, any compiler, any architecture, etc).My question is about std::array::operator[]. Because it is non-constexpr, one needs to use std::get() instead to achieve constexpr-ness, unless a C++14 compiler is used.#include <array>#include <iostream>#include <climits>// Some recursion witchcrafttemplate <typename T, size_t size, size_t index = size - 1>struct StdArrayContains_ {    constexpr static inline bool contains(T elem, const std::array<T, size>& array) {        return std::get<index>(array) == elem || StdArrayContains_<T, size, index - 1>::contains(elem, array);    }};template <typename T, size_t size>struct StdArrayContains_<T, size, 0> {    constexpr static inline bool contains(T elem, const std::array<T, size>& array) {        return std::get<0>(array) == elem;    }};struct TemplateArgs {    constexpr static size_t size = 4;    // Some query/getter methods    constexpr static std::array<int, size> values() {        return {1, 2, 3, 4};    }    constexpr static bool contains(int elem) {        return StdArrayContains_<int, size>::contains(elem, values());    }    // Some methods used for testing    template <typename CharT, typename CharTraits>    static inline std::basic_ostream<CharT, CharTraits>&     print(std::basic_ostream<CharT, CharTraits>& os) {        os << Size:  << size << std::endl;        os << Elements: {;        const char* sep = ;        for (auto& elem : values()) {            os << sep << elem;            sep = , ;        }        os << } << std::endl;        return os;    }    template <typename CharT, typename CharTraits>    static inline std::basic_ostream<CharT, CharTraits>&     printContains(int elem, std::basic_ostream<CharT, CharTraits>& os) {        os             << Contains the element ' << elem << '?             << contains(elem) << std::endl;        return os;    }};int main(void) {    constexpr int validElem = 2, invalidElem = 5;    static_assert( TemplateArgs::contains(validElem), );    static_assert(!TemplateArgs::contains(invalidElem), );    // Testing    std::cout << std::boolalpha;    TemplateArgs::printContains(validElem, std::cout);    TemplateArgs::printContains(invalidElem, std::cout);    TemplateArgs::print(std::cout);    return 0;}The implementation works (compiles and executes without errors or warnings), but I'm wondering if I'm letting anything pass by, or if there is anything that's not allowed by the standard. For example:Is TemplateArgs::contains() truly constexpr? The argument to the function elem is not constexpr itself, but is being passed around in a lot of constexpr code.Is there any better option that's C++11-compliant (for example, implement a fully constexpr std::array, although I failed miserably at that)?This is my system, by the way:[flisboac@sonic ~]$ g++ -v && uname -a && lsb_release -aUsing built-in specs.COLLECT_GCC=g++COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/6.2.1/lto-wrapperTarget: x86_64-pc-linux-gnuConfigured with: /build/gcc-multilib/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=releaseThread model: posixgcc version 6.2.1 20160830 (GCC) Linux sonic 4.8.13-1-ARCH #1 SMP PREEMPT Fri Dec 9 07:24:34 CET 2016 x86_64 GNU/LinuxLSB Version:    1.4Distributor ID: ArchDescription:    Arch LinuxRelease:    rollingCodename:   n/aThe whole template-based set's implementation is here, if anyone is curious to see.
Substitute for `std::array::operator[]` in C++11 by using template-based recursion
c++;c++11;array;set