I have a non-template class (Uart) and want to create template constructor. It needs to take another template class object (SafeQueue). Then this constructor will call another template function defined inside the class.
class signatures are given below;
class UartCommunication
{
public:
UartCommunication(const char *port, speed_t baudRate);
template <typename SendStruct, typename ReceiveStruct, typename SendQueue = SafeQueue<SendStruct>, typename ReceiveQueue = SafeQueue<ReceiveStruct>>
UartCommunication(const char* port, speed_t baudRate,
SendQueue& sendQueue, ReceiveQueue& receiveQueue,
int pollingTime, bool sendIfReceived)
{
port_ = port;
baudRate_ = baudRate;
serial_fd_ = open(port_, O_RDWR | O_NOCTTY | O_NDELAY);
if (serial_fd_ == -1)
{
std::cerr << "Error opening serial port" << std::endl;
// Handle error
}
std::cout << "serial_fd_:" << serial_fd_ << std::endl;
ConfigureSerialPort();
// Start a thread to receive data
receiveThread_ = std::thread(&SendAndReceiveStruct<SendStruct, ReceiveStruct>, this,
sendQueue, receiveQueue, pollingTime, sendIfReceived);
}
// SentAndReceiveStruct from UART
template <typename SendStruct, typename ReceiveStruct, typename SendQueue = SafeQueue<SendStruct>, typename ReceiveQueue = SafeQueue<ReceiveStruct>>
void SendAndReceiveStruct(SendQueue& sendQueue, ReceiveQueue& receiveQueue, int pollingTime, bool sendIfReceived)
{
///codes
}
}
///
// A threadsafe-queue.
template <class T>
class SafeQueue
{
}
I can build the code without creating any object from Uart class using template const. Actually SendAndReceiveStruct function has the same signature with the const and can be called in a thread function. But when I try to create a Uart object with a similar way;
UartCommunication<InputStruct, OutputStruct> pcUart("/dev/ttyUSB0", B921600, AlgoTester::safeQueueInstanceAlgoInput, AlgoTester::safeQueueInstanceAlgoOutput, 20, false);
I get class "UartCommunication" may not have a template argument listC/C++(519) ‘UartCommunication’ is not a templateGCC error. I'm providing the template of the SafeQueue instance but is it ambiguous to use it like that? I need to use the safequeue tempalte as an object, so I cant directly use safequeue object as a template.
Thanks for the help.
Template constructors are meant to work with template argument deduction. Possible work-arounds:
E.g. 2nd method:
class UartCommunication
{
public:
UartCommunication(UartCommunication&&) /*...*/
template <typename SendStruct, typename ReceiveStruct, typename SendQueue = SafeQueue<SendStruct>, typename ReceiveQueue = SafeQueue<ReceiveStruct>>
friend UartCommunication make_uart(const char*, speed_t,
SendQueue& , ReceiveQueue& ,
int , bool );
}
// define make_uart
int main()
{
UartCommunication uart = make_uart<InputStruct, OutputStruct> ( /*...*/);
}