我有一个类T
,我想让这段代码不能编译:
void PassByValue(T);
但允许所有这些:
void PassByRefernce(T&);
void PassByPointer(T*);
注意:我希望它是非法的(即生成编译错误),以声明一个按T
取值的函数,即使该函数从未被使用或定义过。< / p>
编辑:请注意以下是完全有效的C ++:
class T {
public:
T() {}
private:
// Prevent copy/assignment
T(const T&);
T& operator=(const T&);
};
void Fn(T); // I want this line to error, even if the function is never used.
int main() { return 0; }
答案 0 :(得分:4)
这不是严格可能的(见下文),你可以做的最好的事情就是通过使T
不可复制来使这种功能无法使用/无法确定。
通过删除复制文件来完成,如下所示:
class T
{
T(const T&) =delete;
T& operator=(const T&) =delete;
.....
};
如果你不能使用C ++ 11,那么同样的效果会使这些声明变为私有:
class T
{
public:
.....
private:
T(const T&);
T& operator=(const T&);
};
无需实施。
通过这种方式,类无法从另一个实例接收状态,因此传递给函数的唯一方法是通过间接(通过引用或指针)。
当然,这不会“解决”(字面上)原始问题,因为声明像
这样的事情void func(T);
仍有可能。但是,不可能调用该函数,因此授予T的安全性。
不幸的是,对于今天如何定义C ++语言,没有“干净”的解决方案,因为像
这样的代码struct A;
void func(A);
必须编译。
虽然代码本身什么都不做(它只是声明了一些符号),struct A;
中没有任何内容可以说明A
语义。要拒绝func
的声明,我们必须在包含或包含完整A
声明的翻译单元(CPP文件)内(以便我们可以知道不可能复制),必须 - point - 优先于func之一。但是,在包含上述代码段的所有翻译单元中,这种情况并非必要。
有些语言可以做到这一点:想到D,只是留在“系统语言域”。但D-允许“在完全声明之前使用” - 不“包含源”但是“导入模块”(编译器可以访问完整定义)支持迭代转换(如果某些东西尚未定义并在后面定义编译器)回到“精炼”并重复直到它“收敛”到一致的代码,或者如果发现不一致则拒绝代码)。并且 - 由于其“导入机制”和语义/句法分离,无法链接到(大部分)C ++,但只接受C编译库或objs。 (并要求标题的C到D翻译!)
C ++翻译版会逐渐演变为类似D的翻译吗?很难说。在必须保留C“包含模型”的C向后兼容性时非常不可能。
答案 1 :(得分:0)