厳密には可能ではありません (以下を参照)。最善の方法は、そのような関数をコピー不可にして使用不可/定義不可にすることT
です。
これは、次のようにコピー ctor を削除することによって行われます。
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
は、完全な宣言を含む、または含む翻訳単位 (CPP ファイル) 内になければなりませんA
(そのため、コピーが不可能であることを知ることができます)。しかし、これは、上記のスニペットが含まれているすべての翻訳単位で必ずしも発生するわけではありません。
それができる言語があります。「システム言語ドメイン」にとどまるために、D を考えてみてください。しかし、「完全に宣言する前に使用する」ことを許可する D は、「ソースを含める」のではなく、「モジュールをインポートする」(コンパイラが完全な定義にアクセスできる) 反復変換をサポートします (何かがまだ定義されておらず、後でコンパイラが定義されている場合)。 「洗練」に戻り、一貫したコードに「収束」するまで繰り返すか、矛盾が見つかった場合はコードを拒否します)。また、その「インポート メカニズム」とセマンティック/シンタックスの分離のため、(ほとんどの) C++ にリンクできず、C でコンパイルされたライブラリまたは obj のみを受け入れます。(そしてヘッダーの C から D への変換が必要です!)
C++ 変換パスは、D のような変換パスに進化しますか? 言いにくい。C の「包含モデル」の C 下位互換性を保持する必要がある間は、ほとんどありません。