Принимать только определенное целое во время компиляции - PullRequest
1 голос
/ 06 ноября 2019

Некоторые именованные требования, такие как Allocator , требуют, чтобы вы реализовали довольно общие методы, например Allocator::allocate(int n). В моем конкретном случае я хочу реализовать аргумент n=1, и, если возможно, он потерпит неудачу при время компиляции , если будет указано другое целое число.

Пока что яне нашли ни одного надежного решения. Я забочусь только о GCC и Clang.

  • Это прекрасно работает в GCC, но не в Clang ( Godbolt ):

    struct OneAndOnlyOne {
        constexpr OneAndOnlyOne(int v) noexcept {
            // static link-time error in Clang for any value of v unless -O2 is supplied:
            if (v != 1) _you_must_supply_a_one();
        }
    private:
        void _you_must_supply_a_one();
    };
    
  • assert создает проблему во время выполнения ( Godbolt ):

    struct OneAndOnlyOne {
        constexpr OneAndOnlyOne(int v) noexcept {
            // fails only at runtime:
            assert(v == 1);
            (void) v;
        }
    };
    
  • static_assert также не работает: ( Godbolt):

    struct OneAndOnlyOne {
        constexpr OneAndOnlyOne(int v) noexcept {
            // "error: 'v' is not a constant expression"
            static_assert(v == 1);
        }
    };
    
  • Кажется, нет смысла превращать аргумент в параметр шаблона ( Godbolt ):

    template <int> struct FailUnlessOne;
    template <> struct FailUnlessOne <1> {};
    
    struct OneAndOnlyOne {
        constexpr OneAndOnlyOne(int v) noexcept {
            // "error: 'v' is not a constant expression"
            constexpr FailUnlessOne<v> test;
            (void) test;
        }
    };
    

Есть что-то, что я упустил, или вообще невозможно проверить аргумент во время компиляции?

...