由于存在各种类型的64位数据模型(LLP64/IL32P64,LP64/I32LP64,ILP64,SILP64),指定64位无符号整数文字的标准符合方式是什么?
指定ULL的后缀是否足够?或者我最终会在某些数据模型上将文字解释为128位?
我发现我的C++ 头文件很难用所有完全限定类型(比4个嵌套命名空间一样深)读取(并且输入真的很繁琐).这是一个问题(所有答案都提供了实现它的混乱替代方案,但这不是问题):是否有强烈的理由反对在C++语言的结构和类中引入作用域使用指令(尽管允许使用作用域 -功能声明)?
例如
class Foo : public Bar
{
using namespace System;
using namespace System::Network;
using namespace System::Network::Win32::Sockets;
using Bar::MemberFunc; // no conflict with this
// e.g. of how messy my header files are without scoped using-directive
void FooBar(System::Network::Win32::Sockets::Handle handle, System::Network::Win32::Sockets::Error& error /*, more fully-qualified param declarations... */);
};
Run Code Online (Sandbox Code Playgroud)
既然namespace是一个关键字,我会认为它足够明显,不会与使用声明的范围发生冲突,例如Bar::MemberFunc.
编辑:仔细阅读问题--->我加粗了.提醒:我们不是在讨论如何提高示例的可读性.提示using指令范围的中如何实现在C++语言(通过增加关键字/结构等手段IE)是不是一个答案(如果你能找到实现这个使用现有的C++语言标准的一个优雅的方式,那么它会的当然是一个答案)!
struct A
{
A(const A& src);
A(const char* src);
};
struct B
{
operator A();
operator char*();
};
void test()
{
B v;
A s(v);
}
Run Code Online (Sandbox Code Playgroud)
EDG/Comeau和MSVC允许代码,而GCC 4.4.4,CLANG和BCC拒绝它是不明确的.
一位C++委员会成员回答了这个问题(最初):
这不是模棱两可的; A(const A&)构造函数优于A(const char*)构造函数.const A&参数直接绑定到转换函数的结果,因此转换序列被认为是用户定义的转换,后跟身份转换(13.3.3.1.4p1).const char*参数是用户定义的转换,后跟资格转换,所以情况更糟.
然后,他跟进了这个.
实际上,我错了.虽然用户定义的转换序列中的第二个转换序列确实是一个决胜局,但仔细观察13.3.3.2p3,倒数第二个子弹,揭示了这个决胜局只适用于两个序列包含相同的情况用户定义的转换序列,在本例中不是这种情况.因为一个构造函数的转换序列使用B ::运算符A()而另一个使用b ::运算符char*(),所以在两个用户定义的转换序列之间没有仲裁器,并且它们是不明确的.
我的问题是这个.
13.3.3.2 p3表明,
除非以下规则之一适用,否则相同形式的两个隐式转换序列是不可区分的转换序列.
根据我的理解,关键字是"以下规则之一".这并不意味着说明"相同转换序列"的子弹会覆盖上述所有转发序列.我会认为"S1的等级优于S2的等级"会适用吗?
该pthread_mutex_timedlock文档说abs_timeout需要CLOCK_REALTIME.但是,我们都知道,对于特定持续时间的计时(由于系统时间调整)是不合适的.
有没有办法让pthread锁定超时CLOCK_MONOTONIC可移植?pthread_cond_timedwait也是如此.
我想要一个简单接受无符号整数的可变参数模板.但是,我无法让以下工作.
struct Array
{
template <typename... Sizes> // this works
// template <unsigned... Sizes> -- this does not work (GCC 4.7.2)
Array(Sizes... sizes)
{
// This causes narrowing conversion warning if signed int is supplied.
unsigned args[] = { sizes... };
// ...snipped...
}
};
int main()
{
Array arr(1, 1);
}
Run Code Online (Sandbox Code Playgroud)
任何帮助赞赏.
编辑:如果你想知道,我正在尝试使用可变参数模板来复制以下内容.
struct Array
{
Array(unsigned size1) { ... }
Array(unsigned size1, unsigned size2) { ... }
Array(unsigned size1, unsigned size2, unsigned size3) { ... }
// ... …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码段:
#include <iostream>
int main() {
std::string foo;
foo = -1; // why is the compiler not complaining about this?
std::cout << "1" << std::endl;
std::cout << foo << std::endl;
std::cout << "2" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
实际输出(ideone.com C++ 14模式和GCC 4.8.4):
<no output>
问题:
foo = -1,我得到了正确的标准输出(1和2).编译器编译的是什么foo = -1;导致后续的couts失败?我怀疑根据C++标准(假设C++ 0x),以下链接函数会导致未指定的序列.只是想要一个确认,如果有人可以提供解释,我会很感激.
#include <iostream>
struct TFoo
{
TFoo(int)
{
std::cout<<"TFoo"<<std::endl;
};
TFoo foobar1(int)
{
std::cout<<"foobar1"<<std::endl;
return *this;
};
TFoo foobar2(int)
{
std::cout<<"foobar2"<<std::endl;
return *this;
};
static int bar1()
{
std::cout<<"bar1"<<std::endl;
return 0;
};
static int bar2()
{
std::cout<<"bar2"<<std::endl;
return 0;
};
static int bar3()
{
std::cout<<"bar3"<<std::endl;
return 0;
}
};
int main(int argc, char *argv[])
{
// is the sequence well defined for bar1, bar2 and bar3?
TFoo(TFoo::bar1()).foobar1(TFoo::bar2()).foobar2(TFoo::bar3());
}
Run Code Online (Sandbox Code Playgroud)
*编辑:删除函数的__fastcall说明符(不需要/与问题相关).
例:
// can't forward declare with class Foo::Bar
// actual class
class Foo
{
public:
class Bar // or enum Bar
{
}
};
Run Code Online (Sandbox Code Playgroud)
我接受在当前的C++标准下不允许这样做,但是我无法想出不允许它的理由,特别是对于C++ 0x,我们现在能够转发声明枚举.我想象一个反对它的论据是,如果我们向前声明嵌套类,结果证明它是私有的,那就不允许了.但是,如果在声明命名空间中声明一个类,然后将其声明为外部类的嵌套类,那就不会有太大的不同了.编译器只会给出一个错误(沿着前一个声明的行的错误消息可能与此声明不匹配).
那么为什么它真的不被允许呢?
换句话说(由James McNellis撰写),"为什么Foo :: Bar类;没有提供Foo或Bar的定义?"
**鉴于C++标准委员会认识到使用前向声明通过在C++ 0x中引入枚举的前向声明来减少依赖性和编译时间的好处,肯定这是同一件事的一部分不是吗?
#include <new>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
struct foo {};
inline void* operator new(size_t size, foo*) throw (std::bad_alloc)
{
std::cout << "my new " << size << std::endl;
return malloc(size);
}
inline void operator delete(void* p, foo*) throw()
{
std::cout << "my delete" << std::endl;
free(p);
}
int main()
{
delete new((foo*)NULL) foo;
}
Run Code Online (Sandbox Code Playgroud)
输出(通过ideone):
my new 1
Run Code Online (Sandbox Code Playgroud)
我的想法是,C++会释放一个带有附加参数的对象,并且匹配删除相同的参数,但我显然是不正确的.
获取上述代码调用重载删除的正确方法是什么?
using System;
public class Tester
{
public static void Main()
{
const uint x=1u;
const int y=-1;
Console.WriteLine((x+y).GetType());
// Let's refactor and inline y... oops!
Console.WriteLine((x-1).GetType());
}
}
Run Code Online (Sandbox Code Playgroud)
想象一下上面的代码在以下情况中使用:
public long Foo(uint x)
{
const int y = -1;
var ptr = anIntPtr.ToInt64() + (x + y) * 4096;
return ptr;
}
Run Code Online (Sandbox Code Playgroud)
内联看起来非常安全y,但事实并非如此.语言本身的这种不一致是违反直觉的,而且非常危险.大多数程序员只是内联y,但实际上你最终会出现整数溢出错误.事实上,如果你编写如上所述的代码,你很容易让下一个人在同一条代码内联工作y,甚至没有考虑过两次.
我认为这是C#的一个非常适得其反的语言设计问题.
第一个问题,在C#规范中定义了这种行为,为什么这样设计?
第二个问题,1.GetType()/ (-1).GetType()给出System.Int32.为什么它的表现不同const int y=-1?
第三个问题,如果它被隐式转换为uint,那么我们如何明确告诉编译器它是一个有符号整数(1i不是一个有效的语法!)?
最后一个问题,这不是语言设计团队所期望的行为(Eric Lippert会加入吗?),可以吗?