Usage of `std::optional` fails under MSVC 14.2 / VS 2019
Usage of std::optional and the << operator will compile fine with gcc/linux but will fail with a template error when tried to be compiled with MSVC 14.2/ Visual Studio 2019:
I prepared a simple code and project to reproduce it:
either
git clone https://github.com/Superlokkus/bug_demo.git
cd bug_demo
git submodule update --init --recursive
mkdir bin
cd bin
cmake ..
cmake --build .
or look simple code is:
void insert_data() {
long id {1337};
auto opt_field = std::optional<double>(4.2);
auto db = get_database();
db << "insert or replace into test(id,opt_field) values (?,?);"
<< id << opt_field;
}
will fail with
C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(905,90): error C2678: binary '<<': no operator found which takes a left-hand operand of type 'sqlite::database_binder' (or there is no acceptable conversion) [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(765,27): message : could be 'sqlite::database_binder &sqlite::operator <<(sqlite::database_binder &,const std::u16string &)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(735,27): message : or 'sqlite::database_binder &sqlite::operator <<(sqlite::database_binder &,const std::string &)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(613,27): message : or 'sqlite::database_binder &sqlite::operator <<(sqlite::database_binder &,const double &)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(586,27): message : or 'sqlite::database_binder &sqlite::operator <<(sqlite::database_binder &,const float &)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(559,27): message : or 'sqlite::database_binder &sqlite::operator <<(sqlite::database_binder &,const sqlite_int64 &)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(533,27): message : or 'sqlite::database_binder &sqlite::operator <<(sqlite::database_binder &,const int &)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(674,26): message : or 'sqlite::database_binder &sqlite::operator <<(sqlite::database_binder &,std::nullptr_t)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(905,41): message : or 'sqlite::database_binder &&sqlite::operator <<<std::optional
>(sqlite::database_binder &&,const T &)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] with [ T=std::optional ] C:\Users\markus\develop\bug_demo\vendor\sqlite_modern_cpp\hdr\sqlite_modern_cpp.h(905,90): message : while trying to match the argument list '(sqlite::database_binder, const T)' [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] with [ T=std::optional ] C:\Users\markus\develop\bug_demo\main.cpp(25): message : see reference to function template instantiation 'sqlite::database_binder &&sqlite::operator <<<std::optional >(sqlite::database_binder &&,const T &)' being compiled [C:\Users\markus\develop\bug_demo\bin\bug_demo.vcxproj] with [ T=std::optional ]
Besides some warnings about
sqlite_modern_cpp\lists/error_codes.h(6,1): warning C4065: switch statement contains 'default' but no 'case' labels
Working around the issue with unique_ptr works, I guess only some overload where forgotten, I assume the same is true for std::variant
BTW: a simple add_compile_definitions(MODERN_SQLITE_STD_OPTIONAL_SUPPORT) fixed the issue, so I guess the preprocessor compiler support discovery is flawed.
no it is an experimental feature (at least in the latest dev) so you need to enable it explicitly