Expected ',' or '...' before '.' token in constructor - c++11

Having the following code:
SockAddrIn.h
#pragma once
#include <winsock2.h>
#include <string>
namespace networking
{
class SockAddrIn
{
public:
SockAddrIn() {}
SockAddrIn(const std::string& ip, uint16_t port);
SockAddrIn(uint16_t sin_family, unsigned long s_addr, uint16_t port);
SockAddrIn(struct sockaddr_in sin)
: m_sin(sin)
{}
virtual ~SockAddrIn() {}
operator struct sockaddr_in();
operator struct sockaddr_in*();
operator struct sockaddr*();
private:
struct sockaddr_in m_sin;
};
}
SockAddrIn.cpp
#include "networking/SockAddrIn.h"
#include <winsock2.h>
using namespace networking;
SockAddrIn::SockAddrIn(
const std::string& ip,
uint16_t port)
: SockAddrIn(AF_INET, inet_addr(ip.c_str()), htons(port))
{}
SockAddrIn::SockAddrIn(
uint16_t sin_family,
unsigned long s_addr,
uint16_t port)
{
m_sin.sin_family = sin_family;
m_sin.sin_addr.s_addr = s_addr;
m_sin.sin_port = port;
}
SockAddrIn::operator struct sockaddr_in()
{
return ( m_sin );
}
SockAddrIn::operator struct sockaddr_in*()
{
return ( &m_sin );
}
SockAddrIn::operator struct sockaddr*()
{
return ( (struct sockaddr*)&m_sin );
}
The following error is generated (Line 15 is the 3rd constructor):
include\networking\SockAddrIn.h|15|error: expected ',' or '...' before '.' token|
src\networking\SockAddrIn.cpp||In constructor 'networking::SockAddrIn::SockAddrIn(const string&, uint16_t)':|
hi_client\src\networking\SockAddrIn.cpp|11|error: no matching function for call to 'networking::SockAddrIn::SockAddrIn(int, long unsigned int, u_short)'|
hi_client\src\networking\SockAddrIn.cpp|11|note: candidates are:|
include\networking\SockAddrIn.h|16|note: networking::SockAddrIn::SockAddrIn(sockaddr_in)|
include\networking\SockAddrIn.h|16|note: candidate expects 1 argument, 3 provided|
include\networking\SockAddrIn.h|15|note: networking::SockAddrIn::SockAddrIn(uint16_t, long unsigned int)|
include\networking\SockAddrIn.h|15|note: candidate expects 2 arguments, 3 provided|
include\networking\SockAddrIn.h|14|note: networking::SockAddrIn::SockAddrIn(const string&, uint16_t)|
include\networking\SockAddrIn.h|14|note: candidate expects 2 arguments, 3 provided|
include\networking\SockAddrIn.h|13|note: networking::SockAddrIn::SockAddrIn()|
include\networking\SockAddrIn.h|13|note: candidate expects 0 arguments, 3 provided|
include\networking\SockAddrIn.h|10|note: constexpr networking::SockAddrIn::SockAddrIn(const networking::SockAddrIn&)|
include\networking\SockAddrIn.h|10|note: candidate expects 1 argument, 3 provided|
src\networking\SockAddrIn.cpp|16|error: expected ',' or '...' before '.' token|
src\networking\SockAddrIn.cpp||In constructor 'networking::SockAddrIn::SockAddrIn(uint16_t, long unsigned int)':|
src\networking\SockAddrIn.cpp|20|error: request for member 'S_addr' in 'S_un', which is of non-class type 'long unsigned int'|
src\networking\SockAddrIn.cpp|21|error: 'port' was not declared in this scope|
||=== Build failed: 5 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
It looks like something about the 'unsigned long' part irritates the compiler.. Couldn't find anything on the web. This looks really weird to me.. What am I missing?

s_addr is defined as a macro in winsock2.h (or a header inaddr.h included by winsock2.h, to be precise). Like this:
#define s_addr S_un.S_addr /* can be used for most tcp & ip code */
This turns your constructor declaration into nonsense:
SockAddrIn(uint16_t sin_family, unsigned long s_addr, uint16_t port);
// becomes
SockAddrIn(uint16_t sin_family, unsigned long S_un.S_addr, uint16_t port);

Related

Is there a way to create unique type Id at compile time in C++

I can create a unique type id the following way:
template<typename T>
struct TypeId
{
static size_t value()
{
return reinterpret_cast<size_t>(&TypeId<T>::value);
}
};
auto intType = TypeId<int>::value();
It works at runtime but is there a way to do it at compile time ?
I would like to use it in a switch statement like this:
switch (typeId)
{
case TypeId<int>::value():
// do something
break;
case TypeId<double>::value():
// do something
break;
case TypeId<MyClass>::value():
// do something
break;
}
The problem here is that I cannot convert a pointer to the size_t at compile time:
template<typename T>
struct TypeId
{
static constexpr size_t value()
{
return reinterpret_cast<size_t>(&TypeId<T>::value);
}
};
constexpr auto id = TypeId<int>::value();
The example above gives the following error:
error: conversion from pointer type ‘size_t (*)() {aka long unsigned int (*)()}’ to arithmetic type ‘size_t {aka long unsigned int}’ in a constant expression
constexpr auto id = TypeId<int>::value();
UPDATE
I would like to understand why returning an address is fine in a constexpr but converting it to an int is not. The following code compiles (but I cannot use pointers in a switch statement):
template<typename T>
struct TypeId
{
static constexpr void* value()
{
return reinterpret_cast<void*>(&TypeId<T>::value);
}
};
constexpr void* id = TypeId<int>::value();
std::cout << "id: " << id << std::endl;
This sounds like an XY problem. If you want to get compile-time type information, then use compile-time ways to do this. The right way to do this is with std::is_same.
if(std::is_same<int, T>::value) {
// do something
} else if (std::is_same<double, T>::value) {
// do something else
} // ...
This can cause certain problems. if you're using methods for specific types, like std::string::length() in your conditions, you'll have a compile error. There are ways to solve this:
Use if constexpr
Use std::enable_if to create template specializations that are dependent on the type
If you have only pointer-type problems, you have to reinterpret_cast all your pointers to T
There is currently no way in C++ to automatically allocate a unique integer type id and make it availabe compile time.
This is why libraries that need it use manual type registration, e.g.:
template<class T> struct TypeId;
#define REGISTER_TYPE_ID(T, id_value) template<> struct TypeId<T> { static constexpr int id = id_value; };
REGISTER_TYPE_ID(bool, 1)
REGISTER_TYPE_ID(char, 2)
REGISTER_TYPE_ID(unsigned char, 3)
REGISTER_TYPE_ID(unsigned short, 4)
REGISTER_TYPE_ID(unsigned int, 5)
REGISTER_TYPE_ID(unsigned long, 6)
REGISTER_TYPE_ID(unsigned long long, 7)
REGISTER_TYPE_ID(signed char, 8)
REGISTER_TYPE_ID(signed short, 9)
REGISTER_TYPE_ID(signed int, 10)
REGISTER_TYPE_ID(signed long, 11)
REGISTER_TYPE_ID(signed long long, 12)
REGISTER_TYPE_ID(float, 13)
REGISTER_TYPE_ID(double, 14)
REGISTER_TYPE_ID(long double, 15)

C++ E0147 declaration is incompatible with static object

Websource.hpp
#ifndef WEBSOURCE_HPP
#define WEBSOURCE_HPP
#pragma once
class Colour
{
public:
unsigned char _ucRed;
unsigned char _ucGreen;
unsigned char _ucBlue;
Colour(unsigned char i_red, unsigned char i_green, unsigned char i_blue);
Colour(Colour& c);
Colour();
void setColour(unsigned char i_red, unsigned char i_green, unsigned char i_blue);
};
Colour::Colour(unsigned char i_red, unsigned char i_green, unsigned char i_blue)
{
this->setColour(i_red, i_green, i_blue);
}
Colour::Colour(Colour& c)
{
this->setColour(c._ucRed, c._ucGreen, c._ucBlue);
}
Colour::Colour()
{
this->setColour((unsigned char)0, (unsigned char)0, (unsigned char)0);
}
void Colour::setColour(unsigned char i_red, unsigned char i_green, unsigned char i_blue)
{
this->_ucRed = i_red;
this->_ucGreen = i_green;
this->_ucBlue = i_blue;
}
#endif
Website.hpp
#ifndef WEBSITE_HPP
#define WEBSITE_HPP
#pragma once
#include "Websource.hpp"
template <typename T, int N = 16>
class Page {
public:
static Colour c_logo; // logo colour
};
Colour website::Page<double>::Page::c_logo();
#endif
This code leads to Error 0147.
Severity Code Description Project File Line Suppression State Error
(active) E0147 declaration is incompatible with "Colour
website::Page::c_logo [with T=double, N=16]" (declared at line
31 of
"c:\Users\hasler\Documents\ga_design\Website.hpp") ga_design c:\Users\hasler\Documents\ga_design\Website.hpp 88
However, using another constructor works like a charm:
Colour website::Page<double>::Page::c_logo(0,0,0);
And I'm here struggling to understand why one constructor would work and another wouldn't.
To mark the question as answered: "It's a case of the most vexing parse in C++. Using Colour website::Page::Page::c_logo; will work." – R Sahu

std::initializer_list with Multiple Types

I'm having trouble with std::initializer_list. I reduced it down to a simple example:
#include <initializer_list>
#include <cstdio>
class Test {
public:
template <typename type> Test(const std::initializer_list<type>& args) {}
};
int main(int argc, char* argv[]) {
Test({1,2});
getchar();
return 0;
}
When compiled using g++ test_initializer.cpp -std=c++0x, it compiles and runs well. However, if line 11 is changed to Test({1,2.0});, one gets:
ian#<host>:~/Desktop$ g++ test_initializer.cpp -std=c++0x
test_initializer.cpp: In function ‘int main(int, char**)’:
test_initializer.cpp:11:14: error: no matching function for call to ‘Test::Test(<brace-enclosed initializer list>)’
test_initializer.cpp:11:14: note: candidates are:
test_initializer.cpp:7:28: note: template<class type> Test::Test(const std::initializer_list<_Tp>&)
test_initializer.cpp:5:7: note: constexpr Test::Test(const Test&)
test_initializer.cpp:5:7: note: no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘const Test&’
test_initializer.cpp:5:7: note: constexpr Test::Test(Test&&)
test_initializer.cpp:5:7: note: no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘Test&&’
I suspect this happens because the compiler can't figure out what type to make the initializer list. Is there a way to fix the example so that it works with different types (and still uses initializer lists)?
An std::initializer_list takes only one type. If you need different types, you can use variadic templates:
template<typename... Args>
Test(Args&&... args);
/* ... */
int main()
{
Test(1, 2.0);
}
Would a std::tuple<int.double> work for the OP? If the code will always have a int followed by a double, then the OP could get strict type-checking for all arguments, which the variable arguments solution does not allow. The std::tuple<>, however, would not work for any number or order of values, so may not be appropriate for all use cases.
Let the initializer_list hold the most arbitrary pointers, void*, and do your own casting from there. Here is an example.
#include <initializer_list>
#include <iostream>
using std::initializer_list;
using std::cout;
using std::endl;
class Person {
private:
string _name;
int _age;
public:
Person(initializer_list<void*> init_list) {
auto it = init_list.begin();
_name = *((string*)(*it));
it++;
_age = *((int*)(*it));
}
void print() {
cout << "name: " << _name << ". age: " << _age << endl;
}
};
int main(void) {
string name{"Vanderbutenburg};
int age{23};
Person p{&name,&age};
p.print(); // "name: Vanderbutenburg. age: 23"
return 0;
}

VC++ WINAPI Form: Identifier Not Found (C3861 Error)

I'm working on a port from some old Delphi code to VC++ 2013, and I'm encountering an error that I feel should be an easy fix but cannot for the life of me figure out...
The problem is this: I have a number of common utility functions in a local file Utils.h that I am deploying as part of a windows form. Most (90%) of the functions in this header work as normal. GetMsg(...), however, throws a C3861 Identifier not found error...
Utils.h (snippet): GetMsg declared at bottom
#pragma once
/*------------------------------------------------------------------------*
Includes:
*------------------------------------------------------------------------*/
using namespace std;
/*------------------------------------------------------------------------*
Constants:
*------------------------------------------------------------------------*/
#define GET_MSG_TIMEOUT 2
/*------------------------------------------------------------------------*
Typedefs, Structs, Enums:
*------------------------------------------------------------------------*/
typedef union
{
unsigned long ui32;
unsigned char ui8[4];
} UI32_UI8;
typedef union
{
unsigned short ui16;
unsigned char ui8[2];
} UI16_UI8;
typedef union
{
float f;
unsigned char ui8[4];
} F_UI8;
typedef struct
{
string sName;
string sVersion;
string sCompany;
string sCopyright;
} PRODUCT_INFORMATION;
/*------------------------------------------------------------------------*
Prototypes:
*------------------------------------------------------------------------*/
unsigned short SwapShort(unsigned short aShort);
float SwapFloat(float aFloat);
unsigned long SwapLong(unsigned long aLong);
unsigned int ReadLine(unsigned char *msgBuf, SerialPort^ Hdl, bool ReturnLF);
void __stdcall FillTheBuffer(char *buf, String sss, int length);
string __stdcall FillTheString(string sss, int length);
unsigned int __stdcall GetMsg(SerialPort^ Hdl, unsigned char *msgBuf);
GetMsg Definition in Utils.cpp:
//---------------------------------------------------------
unsigned int __stdcall GetMsg(SerialPort^ Hdl, unsigned char *msgBuf)
{
...
}
And, finally, GetMsg usage in form file:
#include "Utils.h"
...
void MainForm::UploadButton_Click
(System::Object^ object, System::EventArgs^ e)
{
...
SwapShort(1); //Works fine, also declared in Utils.h
GetMsg(spCom, inBuf); //C3861 ERROR
...
}
Where spCom is a (SerialPort^) contained, configured, and opened within the windows form. inBuf is a simple array of characters (char*) to buffer the input. I've tried renaming the function, thinking that there may have been an unintentional conflict / overload in other files, to no avail.
Any advice? Thanks, in advance
Solved the problem -- As it turns out I needed to be more explicit in my function definitions. Changing the declaration to read
GetMsg(System::IO::Ports::SerialPort^ Hdl, unsigned char *msgBuf)
eliminated the C3861 error. It would seem that the lack of a specific namespace on the declaration passed Intellisense but confused the compiler, rendering it unable to determine which prototype to use with the function call.

Length of user-defined string literal as a template argument?

Is there any way to get behavior like this?
// Some definition(s) of operator "" _my_str
// Some definition of function or macro MY_STR_LEN
using T1 = MY_STR_LEN("ape"_my_str);
// T1 is std::integral_constant<std::size_t, 3U>.
using T2 = MY_STR_LEN("aardvark"_my_str);
// T2 is std::integral_constant<std::size_t, 8U>.
It seems not, since the string literals are passed immediately to some_return_type operator "" _my_str(const char*, std::size_t); and never to a literal operator template (2.14.8/5). That size function parameter can't be used as a template argument, even though it will almost always be a constant expression.
But it seems like there ought to be some way to do this.
Update: The accepted answer, that this is not possible without an extra definition per literal, is accurate for C++11 as asked, and also C++14 and C++17. C++20 allows the exact result asked for:
#include <cstdlib>
#include <type_traits>
#include <string_view>
struct cexpr_str {
const char* ptr;
std::size_t len;
template <std::size_t Len>
constexpr cexpr_str(const char (&str)[Len]) noexcept
: ptr(str), len(Len) {}
};
// Essentially the same as
// std::literals::string_view_literals::operator""sv :
template <cexpr_str Str>
constexpr std::string_view operator "" _my_str () noexcept
{
return std::string_view(Str.ptr, Str.len);
}
#define MY_STR_LEN(sv) \
std::integral_constant<std::size_t, (sv).size()>
Reading C++11 2.14.8 carefully reveals that the "literal operator template" is only considered for numeric literals, but not for string and character literals.
However, the following approach seems to give you constexpr access to the string length (but not the pointer):
struct MyStr
{
char const * str;
unsigned int len;
constexpr MyStr(char const * p, unsigned int n) : str(p), len(n) {}
};
constexpr MyStr operator "" _xyz (char const * s, unsigned int len)
{
return MyStr(s, len);
}
constexpr auto s = "Hello"_xyz;
Test:
#include <array>
using atype = std::array<int, s.len>; // OK

Resources