66

非構築関数での暗黙的なキャストを回避するにはどうすればよいですか?
パラメータとして整数を取る
関数がありますが、その関数は文字、bool、long も受け取ります。
暗黙的にキャストすることでこれを行うと思います。
関数が一致する型のパラメーターのみを受け入れ、それ以外の場合はコンパイルを拒否するように、これを回避するにはどうすればよいですか?
「explicit」というキーワードがありますが、非構築関数では機能しません。:\
どうしよう?

次のプログラムはコンパイルされますが、コンパイルしないでください。

#include <cstdlib>

//the function signature requires an int
void function(int i);

int main(){

    int i{5};
    function(i); //<- this is acceptable

    char c{'a'};
    function(c); //<- I would NOT like this to compile

    return EXIT_SUCCESS;
}

void function(int i){return;}

*用語や仮定の誤用は必ず指摘してください

4

8 に答える 8

77

他のすべてのタイプに一致する関数テンプレートを定義します。

void function(int); // this will be selected for int only

template <class T>
void function(T) = delete; // C++11 

これは、直接一致する非テンプレート関数が常に最初に考慮されるためです。次に、直接一致する関数テンプレートが考慮されるためfunction<int>、使用されることはありません。しかし、char などの他のものにfunction<char>は使用されます。これにより、コンパイル エラーが発生します。

void function(int) {}

template <class T>
void function(T) = delete; // C++11 


int main() {
   function(1);
   function(char(1)); // line 12
} 

エラー:

prog.cpp: In function 'int main()':
prog.cpp:4:6: error: deleted function 'void function(T) [with T = char]'
prog.cpp:12:20: error: used here

これは C++03 の方法です。

// because this ugly code will give you compilation error for all other types
class DeleteOverload
{
private:
    DeleteOverload(void*);
};


template <class T>
void function(T a, DeleteOverload = 0);

void function(int a)
{}
于 2012-10-13T22:26:36.383 に答える
25

charは自動的に に昇格するため、直接行うことはできませんint

ただし、トリックに頼ることができます: charas パラメーターを受け取る関数を作成し、それを実装しないでください。コンパイルはできますが、リンカー エラーが発生します。

void function(int i) 
{
}
void function(char i);
//or, in C++11
void function(char i) = delete;

パラメーターを指定して関数を呼び出すとchar、ビルドが中断されます。

http://ideone.com/2SRdMを参照

用語: 非構成関数? コンストラクターではない関数を意味しますか?

于 2012-10-13T22:22:39.633 に答える
8

functionint 以外で呼び出された場合、コンパイル時にエラーが発生する一般的な解決策を次に示します。

template <typename T>
struct is_int { static const bool value = false; };

template <>
struct is_int<int> { static const bool value = true; };


template <typename T>
void function(T i) {
  static_assert(is_int<T>::value, "argument is not int");
  return;
}

int main() {
  int i = 5;
  char c = 'a';

  function(i);
  //function(c);

  return 0;
}

引数の任意の型を機能させますがis_int、型レベルの述語として使用することで機能します。の一般的な実装にis_intは false の値がありますが、int 型の明示的な特殊化には値 true があるため、静的アサートは引数の型が正確であることを保証しintます。そうしないと、コンパイル エラーが発生します。

于 2012-10-13T22:37:16.867 に答える
1

さて、私は以下のコードでこれに答えるつもりでしたが、Visual C ++で動作しますが、目的のコンパイルエラーを生成するという意味で、MinGW g ++ 4.7.1はそれを受け入れ、右辺値参照コンストラクターを呼び出します!

コンパイラのバグに違いないと思いますが、間違っている可能性があります。

とにかく、ここにコードがあります。これは標準に準拠したソリューションであることが判明する可能性があります(または、それが私の側の考えであることが判明する可能性があります!):

#include <iostream>
#include <utility>      // std::is_same, std::enable_if
using namespace std;

template< class Type >
struct Boxed
{
    Type value;

    template< class Arg >
    Boxed(
        Arg const& v,
        typename enable_if< is_same< Type, Arg >::value, Arg >::type* = 0
        )
        : value( v )
    {
        wcout << "Generic!" << endl;
    }

    Boxed( Type&& v ): value( move( v ) )
    {
        wcout << "Rvalue!" << endl;
    }
};

void function( Boxed< int > v ) {}

int main()
{
    int i = 5;
    function( i );  //<- this is acceptable

    char c = 'a';
    function( c );  //<- I would NOT like this to compile
}
于 2012-10-13T23:09:53.180 に答える
1

おそらく、構造体を使用して 2 番目の関数を非公開にすることができます。

#include <cstdlib>

struct NoCast {
    static void function(int i);
  private:
    static void function(char c);
};

int main(){

    int i(5);
    NoCast::function(i); //<- this is acceptable

    char c('a');
    NoCast::function(c); //<- Error

    return EXIT_SUCCESS;
}

void NoCast::function(int i){return;}

これはコンパイルされません:

prog.cpp: In function ‘int main()’:
prog.cpp:7: error: ‘static void NoCast::function(char)’ is private
prog.cpp:16: error: within this context
于 2012-10-13T22:32:07.467 に答える