web-dev-qa-db-ja.com

オーバーロードされた関数の呼び出しがあいまいです

このエラーメッセージはどういう意味ですか?

error: call of overloaded ‘setval(int)’ is ambiguous
huge.cpp:18: note: candidates are: void huge::setval(unsigned int)
huge.cpp:28: note:                 void huge::setval(const char*)

私のコードは次のようになります。

#include <iostream>
#define BYTES 8
using namespace std ;

class huge {
private:
    unsigned char data[BYTES];
public:
    void setval(unsigned int);
    void setval(const char *);  
};

void huge::setval(unsigned int t) {
    for(int i = 0; i< BYTES ; i++) {
        data[i] = t;
        t = t >> 1;
    }
}

void huge::setval(const char *s) {
    for(int i = 0; i< BYTES ; i++)
        data[i] = s[i];
}

int main() {
    huge p;
    p.setval(0);
    return 0;
}
21
Barshan Das

リテラル0は、C++では2つの意味があります。
一方で、値0の整数です。
一方、nullポインター定数です。

setval関数はintまたはchar*、コンパイラは、どのオーバーロードを意味するかを決定できません。

最も簡単な解決策は、0を正しいタイプに。
別のオプションは、たとえば他のテンプレートをテンプレートにすることで、intオーバーロードが優先されるようにすることです。

class huge
{
 private:
  unsigned char data[BYTES];
 public:
  void setval(unsigned int);
  template <class T> void setval(const T *); // not implemented
  template <> void setval(const char*);
};

「int」ではなく「unsigned int」である定数値のタイプを考慮すると、ソリューションは非常に簡単です。

の代わりに:

setval(0)

使用する:

setval(0u)

接尾辞「u」は、コンパイラにこれが符号なし整数であることを伝えます。その後、変換は必要なく、呼び出しは明確になります。

13
Leonardo L.

p.setval(0);を次のものに置き換えます。

const unsigned int param = 0;
p.setval(param);

これにより、定数0がどの型であるかを確実に知ることができます。

3
Null Set

使用する

p.setval(static_cast<const char *>(0));

または

p.setval(static_cast<unsigned int>(0));

エラーが示すように、0のタイプはintです。これは、unsigned intまたはconst char *に簡単にキャストできます。手動でキャストすることで、コンパイラにどのオーバーロードが必要かを伝えます。

1
Eclipse

値をキャストして、どの関数を呼び出すかをコンパイラーが認識できるようにします。

p.setval(static_cast<const char *>( 0 ));

コードをコンパイルした後、コードにセグメンテーション違反があることに注意してください(実際に呼び出したい関数によって異なります)。

1
Mark Loeser

ポインターは単なるアドレスであるため、あいまいです。したがって、intもポインターとして扱うことができます。0(int)は、unsigned intまたはchar *に簡単に変換できます。

簡単な答えは、p.setval()を、それが実装されているタイプの1つであるunsigned intまたはchar *であると明確に呼び出すことです。 p.setval(0U)、p.setval((unsigned int)0)、およびp.setval((char *)0)はすべてコンパイルされます。

ただし、このような類似したタイプのオーバーロードされた関数を定義しないことで、最初はこのような状況を回避することをお勧めします。

1
metamatt