I have a class T and I want to make this code not compile:
void PassByValue(T);
but allow all of these:
void PassByRefernce(T&);
void PassByPointer(T*);
Note: that I want it to be illegal (i.e. generates a compile error) to declare a function taking a T by value even if the function is never used or defined.
Edit: Note that the following is totally valid 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; }
It’s not strictly possible (see below), the best you can do is make such function unusable/undefinable by making
Tuncopyable.It is done by deleting the copy ctor, like this:
If you cannot use C++11, the same effect happens making those declaration as private:
No implementation is required.
In this way the class cannot receive a state from another instance, and hence the only way to pass to a function is by an indirection (via reference or pointer).
Of course this will not “solve” (literally) the original question, since declaration of things like
are still possible. However it will not be possible to call that function, and hence the safety of T is granted.
Unfortunately, for how the C++ language is today defined, no “clean” solution exist, since a code like
must compile.
Although the code itself does nothing (it just declare some symbols) there is nothing in
struct A;saying something aboutAsemantics. To deny the declaration offuncwe must be inside the translation unit (CPP file) that contains or includes the fullAdeclaration (so that we can know no copy is possible), that must – at that point – preceed the one of func. But this happens not necessarilly in all the translation units the above snippet is included.There are languages that can do that: think of D, just to remain in the “system langages domain”. But D -which allow a “use before fully declare”- doesn’t “include sources” but “import modules” (the full definitions are accessible to the compiler) supporting iterative translation (if something is not yet defined and defined later the compiler goes back to “refine” and repeats until it “converges” to consistent code, or rejects the code if it finds inconsistencies). And -because of its “import mechanism” and semantic/syntactic separation, cannot link to (most of) C++, but only accepts C compiled libraries or objs. (and require C to D translation of headers!)
Will C++ translation passes evolve towards a D-like one? Hard to be said. Very unlikely while the C backward compatibility of C “inclusion model” must be retained.