Вирішіть задачу восьми королев під час компіляції [закрито]


39

Чи можете ви вирішити головоломку восьми королеви під час компіляції?

Виберіть будь-який відповідний вихідний формат.

Мене особливо цікавить рішення метапрограмування шаблону C ++, але ви можете використовувати мови, які мають подібні конструкції, як, наприклад, система типу Haskell.

В ідеалі ваша метапрограма виводить усі рішення. Немає жорсткого кодування.


Чому ви не дозволяєте використовувати різні мови?
користувач невідомий

@user: Тому що мене цікавить рішення C ++ TMP. Якщо ви знаєте мову, яка має дуже схожі конструкції, не соромтеся опублікувати відповідь.
Р. Мартіньо Фернандес

Чи можу я також використовувати систему типів Haskell? AFAIK це має бути завершеним.
FUZxxl

@FUZxxl: Так. Я відредагую питання.
Р. Мартіньо Фернандес

Чи достатньо зробити жорстоке рішення?
перестала повертати проти годинника,

Відповіді:


50

Моя метапрограма знаходить усі 92 рішення. Вони друкуються як повідомлення про помилки:

error: 'solution' is not a member of 'print<15863724>'

Це означає, що першу королеву слід розмістити у y = 1, другу - у = 5, третю - у = 8 тощо.

Спочатку кілька корисних метафункцій:

template <typename T>
struct return_
{
    typedef T type;
};

template <bool Condition, typename Then, typename Else>
struct if_then_else;

template <typename Then, typename Else>
struct if_then_else<true, Then, Else> : return_<Then> {};

template <typename Then, typename Else>
struct if_then_else<false, Then, Else> : return_<Else> {};

template <int N>
struct constant
{
    enum { value = N };
};

template <int N>
struct print
{
    // empty body -> member access yields a compiler error involving N
};

Потім дві цікаві метафункції (відзначте однину та множину):

template <int queens, int rows, int sums, int difs, int x, int y>
struct put_queen;

template <int queens, int rows, int sums, int difs, int x>
struct put_queens : constant
     < put_queen<queens, rows, sums, difs, x, 1>::value
     + put_queen<queens, rows, sums, difs, x, 2>::value
     + put_queen<queens, rows, sums, difs, x, 3>::value
     + put_queen<queens, rows, sums, difs, x, 4>::value
     + put_queen<queens, rows, sums, difs, x, 5>::value
     + put_queen<queens, rows, sums, difs, x, 6>::value
     + put_queen<queens, rows, sums, difs, x, 7>::value
     + put_queen<queens, rows, sums, difs, x, 8>::value > {};

template <int queens, int rows, int sums, int difs, int x, int y>
struct put_queen : if_then_else<
    rows & (1 << y) || sums & (1 << (x + y)) || difs & (1 << (8 + x - y)),
    constant<0>,
    put_queens<queens * 10 + y, rows | (1 << y), sums | (1 << (x + y)),
               difs | (1 << (8 + x - y)), x + 1>
>::type {};

Змінна queensзберігає y координати королів, розміщених на дошці. Наступні три змінні зберігають рядки та діагоналі, які вже зайняті королевами. xі yмає бути роз'яснювальним.

Перший аргумент для if_then_elseперевірки блокування поточної позиції. Якщо це так, рекурсія припиняється, повертаючи (безглуздий) результат 0. В іншому випадку королева розміщується на дошці, і процес продовжується наступним стовпцем.

Коли х досягає 8, ми знайшли рішення:

template <int queens, int rows, int sums, int difs>
struct put_queens<queens, rows, sums, difs, 8>
{
    enum { value = print<queens>::solution };
};

Оскільки в printшаблоні немає учасника solution, компілятор генерує помилку.

І нарешті, щоб розпочати процес, ми перевіряємо valueчлена порожньої ради:

int go = put_queens<0, 0, 0, 0, 0>::value;

Повну програму можна знайти на ideone .


2
Мені подобається: 1) використання бітових полів для зберігання даних, 2) вибір методу виводу.
Р. Мартінхо Фернандес

7
Занадто багато дивовижних для однієї відповіді.
st0le

Чи не повинен він також виводити значення x?
DeadMG

2
@DeadMG Значення x кожного розташування королеви - це його позиція в рядку (1-8).
Briguy37

22

Я придумав рішення, яке використовує систему типу Haskell. Я трохи погукнув Google для існуючого рішення проблеми на рівні значення , трохи змінив її, а потім підняв її до рівня типу. Потрібно було багато винаходити. Я також повинен був включити купу розширень GHC.

По-перше, оскільки цілі числа не дозволені на рівні типу, мені потрібно було ще раз винаходити натуральні числа, цього разу як типи:

data Zero -- type that represents zero
data S n  -- type constructor that constructs the successor of another natural number
-- Some numbers shortcuts
type One = S Zero
type Two = S One
type Three = S Two
type Four = S Three
type Five = S Four
type Six = S Five
type Seven = S Six
type Eight = S Seven

Алгоритм, який я адаптував, вносить доповнення та віднімання на натуралі, тому мені довелося також їх винаходити також. Функції на рівні типу визначаються в залежності від класів типу. Для цього потрібні розширення для декількох класів типів параметрів та функціональних залежностей. Класи типу не можуть "повернути значення", тому ми використовуємо для цього додатковий параметр таким чином, як PROLOG.

class Add a b r | a b -> r -- last param is the result
instance Add Zero b b                     -- 0 + b = b
instance (Add a b r) => Add (S a) b (S r) -- S(a) + b = S(a + b)

class Sub a b r | a b -> r
instance Sub a Zero a                     -- a - 0 = a
instance (Sub a b r) => Sub (S a) (S b) r -- S(a) - S(b) = a - b

Рекурсія реалізується за твердженнями класу, тому синтаксис виглядає дещо назад.

Далі були булеви:

data True  -- type that represents truth
data False -- type that represents falsehood

І функція порівняння нерівності:

class NotEq a b r | a b -> r
instance NotEq Zero Zero False                -- 0 /= 0 = False
instance NotEq (S a) Zero True                -- S(a) /= 0 = True
instance NotEq Zero (S a) True                -- 0 /= S(a) = True
instance (NotEq a b r) => NotEq (S a) (S b) r -- S(a) /= S(b) = a /= b

І списки ...

data Nil
data h ::: t
infixr 0 :::

class Append xs ys r | xs ys -> r
instance Append Nil ys ys                                       -- [] ++ _ = []
instance (Append xs ys rec) => Append (x ::: xs) ys (x ::: rec) -- (x:xs) ++ ys = x:(xs ++ ys)

class Concat xs r | xs -> r
instance Concat Nil Nil                                         -- concat [] = []
instance (Concat xs rec, Append x rec r) => Concat (x ::: xs) r -- concat (x:xs) = x ++ concat xs

class And l r | l -> r
instance And Nil True                    -- and [] = True
instance And (False ::: t) False         -- and (False:_) = False
instance (And t r) => And (True ::: t) r -- and (True:t) = and t

ifs також відсутні на рівні типу ...

class Cond c t e r | c t e -> r
instance Cond True t e t  -- cond True t _ = t
instance Cond False t e e -- cond False _ e = e

І при цьому вся підтримуюча техніка, яку я використовував, була на місці. Час самому вирішувати проблему!

Починаючи з функції перевірки, чи нормально додавати королеву до наявної дошки:

-- Testing if it's safe to add a queen
class Safe x b n r | x b n -> r
instance Safe x Nil n True    -- safe x [] n = True
instance (Safe x y (S n) rec,
          Add c n cpn, Sub c n cmn,
          NotEq x c c1, NotEq x cpn c2, NotEq x cmn c3,
          And (c1 ::: c2 ::: c3 ::: rec ::: Nil) r) => Safe x (c ::: y) n r
    -- safe x (c:y) n = and [ x /= c , x /= c + n , x /= c - n , safe x y (n+1)]

Зауважте використання тверджень класу для отримання проміжних результатів. Оскільки повернені значення насправді є додатковим параметром, ми не можемо просто викликати твердження безпосередньо одне від одного. Знову ж таки, якщо ви раніше використовували PROLOG, вам може здатися, що цей стиль трохи знайомий.

Після того, як я вніс кілька змін, щоб усунути потребу в лямбдах (які я міг реалізувати, але вирішив залишити на інший день), так виглядало оригінальне рішення:

queens 0 = [[]]
-- The original used the list monad. I "unrolled" bind into concat & map.
queens n = concat $ map f $ queens (n-1)
g y x = if safe x y 1 then [x:y] else []
f y = concat $ map (g y) [1..8]

mapє функцією вищого порядку. Я думав, що реалізація мета-функцій вищого порядку буде занадто клопотом (знову ж таки лямбда), тому я просто перейшов із більш простим рішенням: оскільки я знаю, які функції будуть відображені, я можу реалізувати спеціалізовані версії mapдля кожної, щоб вони не були функції вищого порядку

-- Auxiliary meta-functions
class G y x r | y x -> r
instance (Safe x y One s, Cond s ((x ::: y) ::: Nil) Nil r) => G y x r

class MapG y l r | y l -> r
instance MapG y Nil Nil
instance (MapG y xs rec, G y x g) => MapG y (x ::: xs) (g ::: rec)

-- Shortcut for [1..8]
type OneToEight = One ::: Two ::: Three ::: Four ::: Five ::: Six ::: Seven ::: Eight ::: Nil

class F y r | y -> r
instance (MapG y OneToEight m, Concat m r) => F y r -- f y = concat $ map (g y) [1..8]

class MapF l r | l -> r
instance MapF Nil Nil
instance (MapF xs rec, F x f) => MapF (x ::: xs) (f ::: rec)

І останню метафункцію можна записати зараз:

class Queens n r | n -> r
instance Queens Zero (Nil ::: Nil)
instance (Queens n rec, MapF rec m, Concat m r) => Queens (S n) r

Все, що залишилося, - це якийсь драйвер, який може придумати машину для перевірки типу для розробки рішень.

-- dummy value of type Eight
eight = undefined :: Eight
-- dummy function that asserts the Queens class
queens :: Queens n r => n -> r
queens = const undefined

Ця мета-програма повинна запускатися в засобі перевірки, тому можна запустити ghciі запитати тип queens eight:

> :t queens eight

Це досить швидко перевищить межу рекурсії за замовчуванням (це 20 років). Щоб збільшити цей ліміт, нам потрібно звернутися ghciдо -fcontext-stack=Nопції, де Nпотрібна глибина стека (N = 1000 і п’ятнадцять хвилин недостатньо). Я ще не бачив цього запуску до завершення, оскільки це займає дуже багато часу, але мені вдалося добігти queens four.

Існує повна програма на ideone з деякими механізмами для гарного друку типів результатів, але вони queens twoможуть працювати лише без перевищення меж :(


Крім цікавого рішення, це цікаве посилання на те, що можна зробити за допомогою логіки класу / екземпляра
Michael Klein

11

C, за допомогою препроцесора

Я думаю, що комітет ANSI зробив свідомий вибір не поширювати препроцесор C до того, як Тюрінг був повним. У будь-якому випадку, це не дуже потужно, щоб вирішити проблему восьми королев. Не будь-яким загальним способом.

Але це можна зробити, якщо ви готові жорстко кодувати лічильники циклів. Звичайно, немає реального способу циклу, але ви можете використовувати самовключення (через #include __FILE__), щоб отримати обмежений тип рекурсії.

#ifdef i
# if (r_(i) & 1 << j_(i)) == 0 && (p_(i) & 1 << i + j_(i)) == 0 \
                               && (n_(i) & 1 << 7 + i - j_(i)) == 0
#  if i == 0
#   undef i
#   define i 1
#   undef r1
#   undef p1
#   undef n1
#   define r1 (r0 | (1 << j0))
#   define p1 (p0 | (1 << j0))
#   define n1 (n0 | (1 << 7 - j0))
#   undef j1
#   define j1 0
#   include __FILE__
#   undef j1
#   define j1 1
#   include __FILE__
#   undef j1
#   define j1 2
#   include __FILE__
#   undef j1
#   define j1 3
#   include __FILE__
#   undef j1
#   define j1 4
#   include __FILE__
#   undef j1
#   define j1 5
#   include __FILE__
#   undef j1
#   define j1 6
#   include __FILE__
#   undef j1
#   define j1 7
#   include __FILE__
#   undef i
#   define i 0
#  elif i == 1
#   undef i
#   define i 2
#   undef r2
#   undef p2
#   undef n2
#   define r2 (r1 | (1 << j1))
#   define p2 (p1 | (1 << 1 + j1))
#   define n2 (n1 | (1 << 8 - j1))
#   undef j2
#   define j2 0
#   include __FILE__
#   undef j2
#   define j2 1
#   include __FILE__
#   undef j2
#   define j2 2
#   include __FILE__
#   undef j2
#   define j2 3
#   include __FILE__
#   undef j2
#   define j2 4
#   include __FILE__
#   undef j2
#   define j2 5
#   include __FILE__
#   undef j2
#   define j2 6
#   include __FILE__
#   undef j2
#   define j2 7
#   include __FILE__
#   undef i
#   define i 1
#  elif i == 2
#   undef i
#   define i 3
#   undef r3
#   undef p3
#   undef n3
#   define r3 (r2 | (1 << j2))
#   define p3 (p2 | (1 << 2 + j2))
#   define n3 (n2 | (1 << 9 - j2))
#   undef j3
#   define j3 0
#   include __FILE__
#   undef j3
#   define j3 1
#   include __FILE__
#   undef j3
#   define j3 2
#   include __FILE__
#   undef j3
#   define j3 3
#   include __FILE__
#   undef j3
#   define j3 4
#   include __FILE__
#   undef j3
#   define j3 5
#   include __FILE__
#   undef j3
#   define j3 6
#   include __FILE__
#   undef j3
#   define j3 7
#   include __FILE__
#   undef i
#   define i 2
#  elif i == 3
#   undef i
#   define i 4
#   undef r4
#   undef p4
#   undef n4
#   define r4 (r3 | (1 << j3))
#   define p4 (p3 | (1 << 3 + j3))
#   define n4 (n3 | (1 << 10 - j3))
#   undef j4
#   define j4 0
#   include __FILE__
#   undef j4
#   define j4 1
#   include __FILE__
#   undef j4
#   define j4 2
#   include __FILE__
#   undef j4
#   define j4 3
#   include __FILE__
#   undef j4
#   define j4 4
#   include __FILE__
#   undef j4
#   define j4 5
#   include __FILE__
#   undef j4
#   define j4 6
#   include __FILE__
#   undef j4
#   define j4 7
#   include __FILE__
#   undef i
#   define i 3
#  elif i == 4
#   undef i
#   define i 5
#   undef r5
#   undef p5
#   undef n5
#   define r5 (r4 | (1 << j4))
#   define p5 (p4 | (1 << 4 + j4))
#   define n5 (n4 | (1 << 11 - j4))
#   undef j5
#   define j5 0
#   include __FILE__
#   undef j5
#   define j5 1
#   include __FILE__
#   undef j5
#   define j5 2
#   include __FILE__
#   undef j5
#   define j5 3
#   include __FILE__
#   undef j5
#   define j5 4
#   include __FILE__
#   undef j5
#   define j5 5
#   include __FILE__
#   undef j5
#   define j5 6
#   include __FILE__
#   undef j5
#   define j5 7
#   include __FILE__
#   undef i
#   define i 4
#  elif i == 5
#   undef i
#   define i 6
#   undef r6
#   undef p6
#   undef n6
#   define r6 (r5 | (1 << j5))
#   define p6 (p5 | (1 << 5 + j5))
#   define n6 (n5 | (1 << 12 - j5))
#   undef j6
#   define j6 0
#   include __FILE__
#   undef j6
#   define j6 1
#   include __FILE__
#   undef j6
#   define j6 2
#   include __FILE__
#   undef j6
#   define j6 3
#   include __FILE__
#   undef j6
#   define j6 4
#   include __FILE__
#   undef j6
#   define j6 5
#   include __FILE__
#   undef j6
#   define j6 6
#   include __FILE__
#   undef j6
#   define j6 7
#   include __FILE__
#   undef i
#   define i 5
#  elif i == 6
#   undef i
#   define i 7
#   undef r7
#   undef p7
#   undef n7
#   define r7 (r6 | (1 << j6))
#   define p7 (p6 | (1 << 6 + j6))
#   define n7 (n6 | (1 << 13 - j6))
#   undef j7
#   define j7 0
#   include __FILE__
#   undef j7
#   define j7 1
#   include __FILE__
#   undef j7
#   define j7 2
#   include __FILE__
#   undef j7
#   define j7 3
#   include __FILE__
#   undef j7
#   define j7 4
#   include __FILE__
#   undef j7
#   define j7 5
#   include __FILE__
#   undef j7
#   define j7 6
#   include __FILE__
#   undef j7
#   define j7 7
#   include __FILE__
#   undef i
#   define i 6
#  elif i == 7
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           j0 + 1, j1 + 1, j2 + 1, j3 + 1, j4 + 1, j5 + 1, j6 + 1, j7 + 1);
#  endif
# endif
#else
#include <stdio.h>
#define _cat(a, b) a ## b
#define j_(i) _cat(j, i)
#define n_(i) _cat(n, i)
#define p_(i) _cat(p, i)
#define r_(i) _cat(r, i)
int main(void)
{
# define i 0
# define j0 0
# include __FILE__
# undef j0
# define j0 1
# include __FILE__
# undef j0
# define j0 2
# include __FILE__
# undef j0
# define j0 3
# include __FILE__
# undef j0
# define j0 4
# include __FILE__
# undef j0
# define j0 5
# include __FILE__
# undef j0
# define j0 6
# include __FILE__
# undef j0
# define j0 7
# include __FILE__
# undef j0
    return 0;
}
#endif

Незважаючи на жахливу кількість повторюваного контенту, дозвольте запевнити, що він справді вирішує проблему восьми королей алгоритмічно. На жаль, одне, що я не міг зробити з препроцесором, - це реалізувати загальну структуру даних стека. Підсумок полягає в тому, що мені довелося жорстко кодувати значення, iде б воно не було використано, щоб вибрати інше значення для встановлення. (На відміну від отримання значень, що може бути зроблено повністю загалом. Ось чому #ifвгорі файлу, і саме це визначає, чи можна додати королеву в поточну позицію, не потрібно було повторювати вісім разів.)

Всередині коду препроцесора, iі jпоказують поточний стан розглядається, в той час r, pі nвідслідковувати, які ранги і діагоналі в даний час недоступні для розміщення. Однак iтакож подвоюється як лічильник, що маркує поточну глибину рекурсії, тому насправді всі інші значення фактично використовують i як своєрідний підпис, так що їх значення зберігаються при відновленні від рекурсії. (А також через серйозні труднощі змінити значення символу препроцесора, не повністю замінивши його.)

Складена програма роздруковує всі 92 рішення. Рішення вбудовуються безпосередньо у виконуваний файл; вихід препроцесора виглядає так:

/* ... #included content from <stdio.h> ... */
int main(void)
{
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           0 + 1, 4 + 1, 7 + 1, 5 + 1, 2 + 1, 6 + 1, 1 + 1, 3 + 1);
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           0 + 1, 5 + 1, 7 + 1, 2 + 1, 6 + 1, 3 + 1, 1 + 1, 4 + 1);
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           0 + 1, 6 + 1, 3 + 1, 5 + 1, 7 + 1, 1 + 1, 4 + 1, 2 + 1);
    /* ... 88 more solutions ... */
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           7 + 1, 3 + 1, 0 + 1, 2 + 1, 5 + 1, 1 + 1, 6 + 1, 4 + 1);
    return 0;
}

Це можна зробити, хоча це явно не повинно.


7

Ось рішення C ++ 11 без шаблонів:

constexpr int trypos(
    int work, int col, int row, int rows, int diags1, int diags2,
    int rowbit, int diag1bit, int diag2bit);

constexpr int place(
    int result, int work, int col, int row, int rows, int diags1, int diags2)
{
    return result != 0 ? result
        : col == 8 ? work
        : row == 8 ? 0
        : trypos(work, col, row, rows, diags1, diags2,
                 1 << row, 1 << (7 + col - row), 1 << (14 - col - row));
}

constexpr int trypos(
    int work, int col, int row, int rows, int diags1, int diags2,
    int rowbit, int diag1bit, int diag2bit)
{
    return !(rows & rowbit) && !(diags1 & diag1bit) && !(diags2 & diag2bit)
        ? place(
            place(0, work*10 + 8-row, col + 1, 0,
                  rows | rowbit, diags1 | diag1bit, diags2 | diag2bit),
            work, col, row + 1, rows, diags1, diags2)
        : place(0, work, col, row + 1, rows, diags1, diags2);
}

int places = place(0, 0, 0, 0, 0, 0, 0);

Рішення кодується у вигляді десяткових цифр, як у відповідях FredOverflow. GCC 4.7.1 компілює вищезазначений файл у наступне джерело збірки з g++ -S -std=c++11 8q.cpp:

    .file   "8q.cpp"
    .globl  places
    .data
    .align 4
    .type   places, @object
    .size   places, 4
places:
    .long   84136275
    .ident  "GCC: (GNU) 4.7.1"
    .section    .note.GNU-stack,"",@progbits

Значення символу places- 84136275, тобто перша королева знаходиться на рівні a8, друга - в b4 тощо.


0

c ++ шаблон із визначеним лише одним класом шаблонів:

template <int N, int mask, int mask2, int mask3, int remainDigit, bool fail>
struct EQ;

template <int N, int mask, int mask2, int mask3>
struct EQ<N, mask, mask2, mask3, 0, false> {
    enum _ { Output = (char [N])1 };
};

template <int N, int mask, int mask2, int mask3, int i>
struct EQ<N, mask, mask2, mask3, i, true> { };

template <int N, int mask, int mask2, int mask3, int i>
struct EQ<N, mask, mask2, mask3, i, false> {
    enum _ { _ = 
             sizeof(EQ<N*10+1, mask|(1<<1), mask2|(1<<(1+i)), mask3|(1<<(1+8-i)), i-1, 
               (bool)(mask&(1<<1)) || (bool)(mask2&(1<<(1+i))) || (bool)(mask3&(1<<(1+8-i)))>) +
             sizeof(EQ<N*10+2, mask|(1<<2), mask2|(1<<(2+i)), mask3|(1<<(2+8-i)), i-1, 
               (bool)(mask&(1<<2)) || (bool)(mask2&(1<<(2+i))) || (bool)(mask3&(1<<(2+8-i)))>) +
             sizeof(EQ<N*10+3, mask|(1<<3), mask2|(1<<(3+i)), mask3|(1<<(3+8-i)), i-1, 
               (bool)(mask&(1<<3)) || (bool)(mask2&(1<<(3+i))) || (bool)(mask3&(1<<(3+8-i)))>) +
             sizeof(EQ<N*10+4, mask|(1<<4), mask2|(1<<(4+i)), mask3|(1<<(4+8-i)), i-1, 
               (bool)(mask&(1<<4)) || (bool)(mask2&(1<<(4+i))) || (bool)(mask3&(1<<(4+8-i)))>) +
             sizeof(EQ<N*10+5, mask|(1<<5), mask2|(1<<(5+i)), mask3|(1<<(5+8-i)), i-1, 
               (bool)(mask&(1<<5)) || (bool)(mask2&(1<<(5+i))) || (bool)(mask3&(1<<(5+8-i)))>) +
             sizeof(EQ<N*10+6, mask|(1<<6), mask2|(1<<(6+i)), mask3|(1<<(6+8-i)), i-1, 
               (bool)(mask&(1<<6)) || (bool)(mask2&(1<<(6+i))) || (bool)(mask3&(1<<(6+8-i)))>) +
             sizeof(EQ<N*10+7, mask|(1<<7), mask2|(1<<(7+i)), mask3|(1<<(7+8-i)), i-1, 
               (bool)(mask&(1<<7)) || (bool)(mask2&(1<<(7+i))) || (bool)(mask3&(1<<(7+8-i)))>) +
             sizeof(EQ<N*10+8, mask|(1<<8), mask2|(1<<(8+i)), mask3|(1<<(8+8-i)), i-1, 
               (bool)(mask&(1<<8)) || (bool)(mask2&(1<<(8+i))) || (bool)(mask3&(1<<(8+8-i)))>)};
};
int main(int argc, _TCHAR* argv[])
{
    // output all solutions to eight queens problems as error messages
    sizeof(EQ<0, 0, 0, 0, 8, false>);
    return 0;
}

тому повідомлення про помилку буде виглядати так:

помилка C2440: 'type cast': не вдається перетворити з 'int' в 'char [15863724]'

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.