Language: C++

# define _SCL_SECURE_NO_WARNINGS

# include <iostream>
# include <string>
# include <iomanip>
# include <cstdio>
# include <array>
# include <numeric>
# include <algorithm>
# include <vector>
# include <functional>
# include <fstream>
# include <random>
# include <bitset>
# include <map>
# include <unordered_set>


// C++ 11 前提

using Ull = unsigned long long;
using Ll = long long;

template<typename T>
using Vec = std::vector<T>;

template<typename T, size_t L>
using Ary = std::array<T, L>;

namespace
{

    namespace meta
    {
        namespace future
        {
        // c++ 17;
            template<class... _Types>
            using void_t = void;

            template<class _Ty,
                _Ty _Val>
                struct integral_constant
            {	// convenient template for integral constant types
                static constexpr _Ty value = _Val;

                using value_type = _Ty;
                using type = integral_constant;

                constexpr operator value_type() const noexcept
                {	// return stored value
                    return (value);
                }

                constexpr value_type operator()() const noexcept
                {	// return stored value
                    return (value);
                }
            };

            // ALIAS TEMPLATE bool_constant
            template<bool _Val>
            using bool_constant = integral_constant<bool, _Val>;
        }

        namespace core
        {

            template < class, class = void > struct enable_std_begin_end : std::false_type {};
            template < typename T >
            struct enable_std_begin_end<T,
                future::void_t<decltype(std::begin(std::declval<const T&>()), std::end(std::declval<const T&>()))>> : std::true_type {}; // c++ 17


            template < class, class = void > struct enable_adl_begin_end : std::false_type {};
            template < typename T >
            struct enable_adl_begin_end<T,
                future::void_t<decltype(begin(std::declval<const T&>()), end(std::declval<const T&>()))>> : std::true_type {};
        }

        template < typename T >
        struct is_range
            : future::bool_constant< core::enable_std_begin_end<T>::value || core::enable_adl_begin_end<T>::value> {};

        /// <summary>
        /// ある値が0以上か
        /// </summary>
        template<class T, T num, class = std::nullptr_t> struct is_positive
            : future::bool_constant<(num >= 0)> {};

    }


    inline namespace extension
    {
        inline namespace container_io
        {
            inline namespace in
            {

                /// <summary>
                /// for cin with STL container
                /// </summary>
                template< template<class ...> class Container, class ... Args >
                std::istream& operator >> (std::istream& is, Container<Args ...>& container)
                {
                    for (auto& elem : container) is >> elem; return is;
                }

                /// <summary>
                /// for cin with std::arary
                /// </summary>
                template<class T, size_t L>
                std::istream& operator >> (std::istream& is, std::array<T, L>& container)
                {
                    for (auto& elem : container) is >> elem; return is;
                }

                /// <summary>
                /// for cin with raw array
                /// </summary>
                template<class T, size_t L>
                std::istream& operator >> (std::istream& is, T(&ary)[L])
                {
                    for (int i{}; i < L; ++i) is >> ary[i]; return is;
                }

            }

            inline namespace out
            {
                namespace settings
                {
                    /// <summary>
                    /// 要素間の区切り文字
                    /// </summary>
                    const auto sepOfContainerElements{" "};
                    /// <summary>
                    /// コンテナ間の区切り文字
                    /// </summary>
                    const auto sepOfContainer{"\n"};
                }


                /// <summary>
                /// for cout Container with STL container
                /// </summary>
                template < template<class ...> class Container, class ... Args >
                std::ostream& operator << (std::ostream& os, const Container<Args ...>& container)
                {
                    for (const auto& elem : container) os << elem << settings::sepOfContainerElements; return os;
                }

                /// <summary>
                /// for cout Container with std::array
                /// </summary>
                template < class T, size_t L>
                std::ostream& operator << (std::ostream& os, const std::array<T, L> container)
                {
                    for (const auto& elem : container) os << elem << settings::sepOfContainerElements; return os;
                }

                /// <summary>
                /// for cout Container with raw array
                /// </summary>
                template < class T, size_t L, typename = std::enable_if_t<!std::is_same<T, char> > >
                std::ostream& operator << (std::ostream& os, const T(&ary)[L])
                {
                    for (const auto& elem : ary) os << elem << settings::sepOfContainerElements; return os;
                }



                /// <summary>
                /// for cout Container in Container with STL container
                /// </summary>
                template < template<class ...> class Container1, class ... Cont1Args,
                    template<class ...> class Container2, class ... Cont2Args  >
                std::ostream& operator << (std::ostream& os, const Container1< Container2<Cont2Args ...>, Cont1Args ...>& container)
                {
                    for (const auto& elem : container) os << elem << settings::sepOfContainer; return os;
                }



                /// <summary>
                /// for cout Container in Container with std::array
                /// </summary>
                template < template<class ...> class Container, class ... Args, size_t L >
                std::ostream& operator << (std::ostream& os, const std::array<Container<Args ...>, L>& container)
                {
                    for (const auto& elem : container) os << elem << settings::sepOfContainer; return os;
                }
                /// <summary>
                /// for cout Container in Container with std::array
                /// </summary>
                template < template<class ...> class Container, class ... Args, size_t L, class T  >
                std::ostream& operator << (std::ostream& os, const Container<std::array<T, L>, Args ...>& container)
                {
                    for (const auto& elem : container) os << elem << settings::sepOfContainer; return os;
                }
                /// <summary>
                /// for cout Container in Container with std::array
                /// </summary>
                template < class T, size_t L1, size_t L2 >
                std::ostream& operator << (std::ostream& os, const std::array<std::array<T, L2>, L1> container)
                {
                    for (const auto& elem : container) os << elem << settings::sepOfContainer; return os;
                }


                /// <summary>
                /// for cout raw ary in raw ary
                /// </summary>
                template < class T, size_t L1, size_t L2 >
                std::ostream& operator << (std::ostream& os, const T(&ary)[L1][L2])
                {
                    for (size_t i{}; i < L1; ++i) os << ary[i] << settings::sepOfContainer; return os;
                }

            }
        }


        template<typename T, size_t L, typename Function>
        void for_each(T(&ary)[L], Function lambda)
        {
            for (size_t i{}; i < L; ++i)
                lambda(static_cast<T&>(ary[i]));
        }
    }


    inline namespace util
    {

        template<typename T>
        void SetAll(T& container, typename T::value_type value = typename T::value_type{})
        {
            for (typename T::reference content : container) content = value;
        }

        template<typename T, size_t L>
        void SetAll(T(&ary)[L], T value)
        {
            for (size_t i{}; i < L; ++i) ary[i] = value;
        }

        template<typename T, typename U, size_t L1, size_t L2>
        void SetAll(T(&ary)[L1][L2], U value)
        {
            for (size_t i{}; i < L1; ++i) SetAll(ary[i], value);
        }
        

        inline namespace ranges
        {

            namespace core
            {

                using namespace meta;
                /// <summary>
                /// 再帰上限回数
                /// </summary>
                constexpr auto recursion_limits{490};

                /// <summary>
                /// 値が割り切れるか
                /// </summary>
                template<int num, int divide> struct is_divisible 
                    : future::bool_constant<num % divide == 0> {};

                /// <summary>
                /// 有限回数の再帰で終わるか
                /// </summary>
                template<int start, int end, int step> struct is_finite_recursion_depth 
                    : future::bool_constant<(start < end) && (step > 0) || (end < start) && (step < 0)>{};

                /// <summary>
                /// 再帰回数が上限を超えないか
                /// </summary>
                template<int start, int end, int step> struct is_valid_recursion_depth
                    : future::bool_constant<(end - start) / step <= recursion_limits> {};

                /// <summary>
                /// 上記メタ関数の条件をすべて満たすか
                /// </summary>
                template<int start, int end, int step> struct is_valid_range
                    : future::bool_constant<(start == end) || is_finite_recursion_depth<start, end, step>::value && is_valid_recursion_depth<start, end, step>::value && is_divisible<end - start, step>::value>{};

                /// <summary>
                /// 再帰を続けるか
                /// </summary>
                template<int start, int end, int step> struct is_count_up_or_down
                    : future::bool_constant<is_valid_range<start, end, step>::value && end != start> {};

                /// <summary>
                /// 初期化子リストからstd::arrayをコンパイル時生成
                /// </summary>
                template<typename T, typename ...Args>
                constexpr std::array<T, sizeof...(Args)> make_array(Args&&... args)
                {
                    return std::array<T, sizeof...(Args)>{ static_cast<Args&&>(args)... };
                }

            
                /// <summary>
                /// 本体
                /// </summary>

                // エラー処理
                template<int start, int end, int step, class = std::nullptr_t, int ...Ary>
                struct Range_Impl
                {
                    //static_assert(is_valid_range           <start, end, step>::value, "[ ! ] invalid teplate argments [ ! ] 値正しくないっぽいヨ！");
                    static_assert(is_divisible             <end -start, step>::value, "[ ! ] (end - start) is indivisible by step number [ ! ] 割り切れないヨ！stepの値確認して！");
                    static_assert(is_finite_recursion_depth<start, end, step>::value, "[ ! ] goes to infinite loop [ ! ] 無限ループなっちゃうヨ！stepの符号逆じゃない？");
                    static_assert(is_valid_recursion_depth <start, end, step>::value, "[ ! ] recursion depth is out of maximum limit [ ! ] 再帰回数が大きくなりすぎｨ壊れちゃううう");
                };
                // 再帰
                template<int start, int end, int step, int ... Ary>
                struct Range_Impl<start, end, step, std::enable_if_t<is_count_up_or_down<start, end, step>::value, std::nullptr_t>, Ary ... >
                    : Range_Impl < start + step, end, step, std::nullptr_t, Ary ..., start> 
                {
                };
                // 終端
                template<int start, int end, int step, int ... Ary>
                struct Range_Impl < start, end, step, std::enable_if_t<start == end, std::nullptr_t>, Ary ...>
                {
                    static constexpr auto value = make_array<int>(Ary ..., end);
                };


            }


            template<size_t size, bool isReverse = false>
            struct Iterate
            {
                static constexpr auto in = isReverse ? 
                    core::Range_Impl<static_cast<int>(size - 1), 0, -1>::value : 
                    core::Range_Impl<0, static_cast<int>(size - 1),  1>::value;
            };

            template<unsigned int upTo>
            struct CountUp
            {
                static constexpr auto to = core::Range_Impl<0, static_cast<int>(upTo), 1>::value;
            };
            template<unsigned int downFrom>
            struct CountDown
            {
                static constexpr auto from = core::Range_Impl<static_cast<int>(downFrom), 0, -1>::value;
            };


            template<int start, int containedEnd, int step = 0, typename = std::nullptr_t>
            struct Range
            {
                static constexpr auto& in = core::Range_Impl<start, containedEnd, step>::value;
            };
            template<int start, int containedEnd>
            struct Range <start, containedEnd, 0>
            {
                static constexpr auto& in = core::Range_Impl<start, containedEnd, meta::is_positive<int, containedEnd - start>::value ? 1 : -1>::value;
            };

        }
    }


    inline namespace alg
    {
        bool IsPrime(const Ull n)
        {
            switch (n)
            {
            case 0: case 1:
                return false;
            case 2:
                return true;
            default:

                if (n % 2 == 0) return false;

                for (Ull i{3}; i * i <= n; i += 2)
                {
                    if (n % i == 0) return false;
                }
            }

            return true;
        }

        // 最大公約数
        Ull EuclideanAlg(Ull n1, Ull n2)
        {
            if (n1 < 0 || n2 < 0) return 0;
            if (n2 > n1) std::swap(n1, n2);

            Ull r;
            while ((r = n1 % n2) != 0)
            {
                n1 = n2;
                n2 = r;
            }

            return n2;
        }

        // 最小公倍数
        Ull LCM(const std::vector<Ull>& values)
        {
            if (values.size() == 0)
                return 0;
            if (values.size() == 1)
                return values[0];
            if (values.size() == 2)
                return values[0] * values[1] / EuclideanAlg(values[0], values[1]);

            auto mid = values.cbegin() + values.size() / 2;

            return LCM(std::vector<Ull>{LCM(std::vector<Ull>(values.begin(), mid)), LCM(std::vector<Ull>(mid, values.end()))});
        }
    }


    void Solve();
}

# if true
int main()
{
    Solve();
    return 0;
}
# endif



namespace
{


    void Solve()
    {
        int i;
        std::cin >> i;
        std::cout << (i > 999 ? "ABD" : "ABC");

    }

}

Compiler output:
a.cc:166:98: error: template argument 1 is invalid
  166 |                 template < class T, size_t L, typename = std::enable_if_t<!std::is_same<T, char> > >
      |                                                                                                  ^