8

I've been having problems trying to get boost.multiprecision to work in my VC2017 project, and I tried to make the simplest project possible as a proof of concept:

#include<boost/multiprecision/cpp_int.hpp>

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

Unfortunately, this code does not compile, with the following errors:

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 ==========

These are the exact same errors I'm getting in the more complex project that originally used boost.multiprecision. I had no problems getting this code to compile in Visual Studio 2015. Does anyone know what's wrong, and what I need to do to fix it?

EDIT:

A project using boost.asio compiles with no issues:

#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;
}
Community
  • 1
  • 1
Xirema
  • 19,889
  • 4
  • 32
  • 68
  • 1
    What version of boost are you using? I've tried your example with 1.63.0 on the latest MSVC 2017 RC and got slightly different compiler output. Anyway, the errors I got were fixed by `#define _HAS_AUTO_PTR_ETC 1` before including the boost header. Does this fix the issue on your side? I can provide more details in an answer if that's the case. – bogdan Feb 03 '17 at 18:51
  • @bogdan I'm using 1.61.0, but I tried a cursory example with 1.63.0 and got (what appeared to me at a cursory glance) identical errors. I'll try your suggestion and see what happens as soon as an opportunity presents itself. – Xirema Feb 03 '17 at 19:34
  • @bogdan That seems to have worked, so if you write that up as an answer, I'll accept it. I would like, if you know of any, a reference or blog post of other macros like that one I should probably be aware of, as I remember having to do something similar to get an older version of a different boost library to work (for an entirely different project), and it seems like knowing those would be handy, and the boost documentation is woefully difficult to parse. – Xirema Feb 04 '17 at 02:49

1 Answers1

18

The problem is caused by the fact that some templates in boost::multiprecision use std::unary_function, which has been deprecated since C++11 and was removed from the standard for C++17.

The standard library implementation in MSVC 2015 introduced guards like #if _HAS_AUTO_PTR_ETC around such deprecated definitions. They are set to 1 by default under the new switch /std:c++14 (the default) and set to 0 by default under /std:c++latest (the new compiler switches are available since 2015 Update 3).

So, until boost removes the dependencies on std::unary_function, you have to either not use /std:c++latest (I've always been using it since it came out) or #define _HAS_AUTO_PTR_ETC 1 before including (directly or indirectly) any standard library headers. So, either set it with compiler options or in some PCH that is the first that gets included in all translation units or something like that.

A thorough description of these settings, including other guards that control other deprecated or removed features, can be found in this blog post by Stephan T. Lavavej. The Visual C++ change history 2003 - 2015 seems to be the official list of breaking changes in MSVC, but unfortunately it doesn't cover all these details. In general, scanning the Visual C++ Team Blog for posts from Stephan will give you the best info on these things.

bogdan
  • 9,229
  • 2
  • 33
  • 48