SqliteModernCpp / sqlite_modern_cpp

The C++14 wrapper around sqlite library
MIT License
903 stars 156 forks source link

Usage of `std::optional` fails under MSVC 14.2 / VS 2019 #209

Open Superlokkus opened 4 years ago

Superlokkus commented 4 years ago

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

Superlokkus commented 3 years ago

BTW: a simple add_compile_definitions(MODERN_SQLITE_STD_OPTIONAL_SUPPORT) fixed the issue, so I guess the preprocessor compiler support discovery is flawed.

codethinki commented 11 months ago

no it is an experimental feature (at least in the latest dev) so you need to enable it explicitly