C2143 / C2518 при попытке скомпилировать проект с использованием boost.multiprecision

У меня были проблемы при попытке заставить boost.multiprecision работать в моем проекте VC2017, и я попытался сделать самый простой проект возможным в качестве доказательства концепции:

#include<boost/multiprecision/cpp_int.hpp>

int main() {
boost::multiprecision::cpp_int val{ 5 };
val *= 5;
val *= 5;
return val.convert_to<int>();
}

К сожалению, этот код не компилируется со следующими ошибками:

1>------ Build started: Project: Multiprecision Test, Configuration: Debug x64 ------
1>Multi Main.cpp
1>Unknown compiler version - please run the configure tests and report the results
1>g:\workspacec\solutions\project4x\library\include\boost\utility\compare_pointees.hpp(36): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\utility\compare_pointees.hpp(40): note: see reference to class template instantiation 'boost::equal_pointees_t<OptionalPointee>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\utility\compare_pointees.hpp(59): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\utility\compare_pointees.hpp(63): note: see reference to class template instantiation 'boost::less_pointees_t<OptionalPointee>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(453): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(467): note: see reference to class template instantiation 'boost::numeric::convdetail::trivial_converter_impl<Traits>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(453): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(454): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(474): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(497): note: see reference to class template instantiation 'boost::numeric::convdetail::rounding_converter<Traits,RangeChecker,RawConverter,Float2IntRounder>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(474): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(475): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(504): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(526): note: see reference to class template instantiation 'boost::numeric::convdetail::non_rounding_converter<Traits,RangeChecker,RawConverter>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(504): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(505): error C2518: keyword 'typename' illegal in base class list; ignored
1>Done building project "Multiprecision Test.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========

Это те же самые ошибки, которые я получаю в более сложном проекте, который изначально использовал boost.multiprecision. У меня не было проблем с получением этого кода для компиляции в Visual Studio 2015. Кто-нибудь знает, что не так, и что мне нужно сделать, чтобы это исправить?

Проект, использующий boost.asio, компилируется без проблем:

#include<boost/asio.hpp>
#include<iostream>

int main() {
boost::asio::io_service service;
for (int i = 0; i < 10; i++) {
service.post([i] {
std::cout << i << std::endl;
});
}
service.run();
system("pause");
return 0;
}

6

Решение

Проблема вызвана тем, что некоторые шаблоны в boost::multiprecision использование std::unary_function, которая устарела с C ++ 11 и была удалена из стандарта для C ++ 17.

В стандартной реализации библиотеки в MSVC 2015 представлены такие элементы защиты, как #if _HAS_AUTO_PTR_ETC вокруг таких устаревших определений. Они настроены на 1 по умолчанию под новым переключателем /std:c++14 (по умолчанию) и установите в 0 по умолчанию под /std:c++latest (новые ключи компилятора доступны с 2015 года, обновление 3).

Итак, пока boost не уберет зависимости от std::unary_functionПриходится либо не использовать /std:c++latest (Я всегда использовал его, так как он вышел) или #define _HAS_AUTO_PTR_ETC 1 перед включением (прямо или косвенно) любых стандартных библиотечных заголовков. Итак, либо установите его с помощью параметров компилятора, либо в какой-нибудь PCH, который будет первым включенным во все блоки перевода, или что-то в этом роде.

Подробное описание этих настроек, включая другие средства защиты, которые контролируют другие устаревшие или удаленные функции, можно найти в этот блог Стефан Т. Лававей. Visual C ++ история изменений 2003 — 2015 похоже, это официальный список серьезных изменений в MSVC, но, к сожалению, он не охватывает все эти детали. В общем, сканирование Visual C ++ Team Blog для сообщений от Стефана даст вам лучшую информацию об этих вещах.

15

Другие решения

Других решений пока нет …