我正在尝试使用https://github.com/gdelugre/literal_ipaddr来表示它是
inet_addr / inet_aton / inet_pton的C ++ 17 constexpr实现
当我这样做时:
auto ipSourceAddressTest = IPAddr::inet_pton<AF_INET>("127.0.0.1");
std::cout << "ipSourceAddressTest is " << ipSourceAddressTest.s_addr << std::endl;
这很好。我得到的IP地址为十进制。
但是:
std::string ipv4address;
//get ipv4address from world here
const unsigned int ipMaxSize = 200;
char ip[ipMaxSize];
std::copy(ipv4address.begin(), ipv4address.end(), ip);
auto ipSourceAddress = IPAddr::inet_pton<AF_INET>(ip);
std::cout << "ipSourceAddress is " << ipSourceAddress.s_addr << std::endl;
请记住,ipSourceAddress.s_addr
是uint32_t
。我打印的值不是IP的十进制,而是实际上的4294967295
,它是二进制的111...111
。因此,我认为它是在编译时而不是在运行时获得其价值的。
如果我这样做
constexpr auto in_addr1 = IPAddr::inet_pton<AF_INET>(ip);
那么可以理解,它的值将在编译时推断出来。但是我没有在变量声明中使用constexpr
。 auto
暗示constexpr
吗?
根据https://en.cppreference.com/w/cpp/language/constexpr,
在函数或静态成员变量中使用的constexpr说明符 (自C ++ 17起)声明暗含内联
那为什么函数inet_pton
在编译时就得到了它的值?
答案 0 :(得分:3)
ipSourceAddress
在编译时未获得其值(如果不遵循规则)。
ip
的值不能在常量表达式中使用,因为它没有声明为constexpr
,并且不符合以下条件中的从左值到右值转换规则的其他例外之一一个常量表达式。因此IPAddr::inet_pton<AF_INET>(ip)
不是常数表达式。
通过使ipSourceAddress
constexpr
(auto
并不意味着)可以清楚地看到这一点。
constexpr
的变量需要在编译时进行初始化,并且由于初始化程序不是常量表达式,因此它将失败。
请参见godbolt。
我不知道你怎么得出不同的结论。
但是请注意,该库似乎确实要求传递给它的char
数组与它包含的字符串一样长(加上空终止符)。如果递给它更长的数组并输出您所看到的值,它将失败。
请参见godbolt。
似乎作者打算仅使用字符串文字直接调用这些函数。