1

I'm having an issue with this. It keeps throwing the error:

use of class template 'std::unique_ptr' requires template arguments

I've searched for an hour. I've tried compiling using c++17, and still didn't work. How can I get the MariaDB Connector to work? I installed the MariaDB Connector. I am on Debian 10. And using clang++ v7 to compile. I tried adding a <template> option in the header, and still didn't work.

I'm compiling using this: clang++ -I/usr/include/mariadb/concpp/compat -O3 -Wall -o ./getUsers ./getUsers.cpp -lmariadbcpp

#include <iostream> 
#include <cstring>
#include <mariadb/conncpp.hpp>

using namespace std;

// Main Process
int main(){
    try {
        // Instantiate Driver
        sql::Driver* driver = sql::mariadb::get_driver_instance();

        // Configure Connection
        sql::SQLString url("jdbc:mariadb://x.x.x.x:3306/todo");
        sql::Properties properties({{"user", "xxxx"}, {"password", "xxxx"}});

        // Establish Connection
        std::unique_ptr conn(driver->connect(url, properties));

        // Create a new Statement
        std::unique_ptr stmnt(conn->createStatement());
        // Execute query
        sql::ResultSet *res = stmnt->executeQuery("SELECT id, username FROM accounts");
        // Loop through and print results
        while (res->next()) {
            std::cout << res->getInt("id") << ") ";
            std::cout << res->getString("username");
        }
    }
    catch(sql::SQLException& e){
      std::cerr << "Error selecting tasks: " << e.what() << std::endl;
   }

   delete res;
   delete stmnt;
   delete conn;

   // Exit (Success)
   return 0;
}
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • `std::unique_ptr` is not a type. It is a template. For example `std::unique_ptr` is a type. Can't you use `auto` ? – 463035818_is_not_an_ai Jun 21 '21 at 14:11
  • don't call `delete x;` when x is a smart pointer. – 463035818_is_not_an_ai Jun 21 '21 at 14:13
  • This is a great beginner question, and the title is super searchable on search engine so it has greater chances to help other. My kudos to OP! I edited the title for the question to be even more searchable. – Guillaume Racicot Jun 21 '21 at 14:15
  • @463035818_is_not_a_number: One might think about C++17 CTAD, but "unavailable" (constructors doesn't allows deduction of `T`) for `std::unique_ptr` :-) – Jarod42 Jun 21 '21 at 14:25
  • @Jarod42 indeed, I was considering CTAD. I think it is unfortunate that a statement like "[name of a template] is not a class" needs a long explanation, and I dislike it when new features make my simple mental model of C++ invalid :P – 463035818_is_not_an_ai Jun 21 '21 at 14:29

1 Answers1

6

The compiler is right: use of class template std::unique_ptr requires template arguments. You must provide template arguments to the std::unique_ptr type.

// ...

//             v---------------v---- template arguments
std::unique_ptr<sql::Connection> stmnt(conn->createStatement());

// ...

//             v----------------------v----- same here
std::unique_ptr<sql::PreparedStatement> stmnt(conn->createStatement());

See How to Connect C++ Programs to MariaDB

C++17 Can normally infer the type of a class template, but std::unique_ptr does not. The std::unique_ptr constructor cannot deduce types due to the way it is defined, and deduction guides has not been added to std::unique_ptr deliberately. This is because both raw arrays and pointers are passed in the same way, so std::unique_ptr cannot distinguish between int* and int[], which are deleted differently. This is a quirk from C that still affect design choices in C++.

Now, you also delete the unique pointers, but this is not recessary.

// Res is not a unique pointer, you still need to delete it.
delete res;

// You don't need that, those are unique pointers, remove it from your code.
delete stmnt;
delete conn;
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141