IT

C ++에서 참조로 전달되는 동안 매개 변수의 라우팅

lottoking 2020. 7. 26. 11:51
반응형

C ++에서 참조로 전달되는 동안 매개 변수의 라우팅


매개 변수를 참조로 전달하는 동안 함수의 매개 변수에 서열을 전달하는 동안 있습니까? C ++에서

예를 들어, 다음과 같은 함수를 선언 할 때 :

virtual const ULONG Write(ULONG &State = 0, bool sequence = true);

이 작업을 수행하면 오류가 발생합니다.

오류 C2440 : 'default argument': 'const int'에서 'unsigned long &'으로 변환 할 수 없습니다. 'const'가 아닌 참조는 lvalue가 아닌 값에 바인딩 할 수 없습니다.


const 참조에 필요한 것은 const가 아닌 참조에 할 수 없습니다. 이는 C ++에서 임시 (이 경우 언급)가 상수가 아닌 참조에 바인딩되는 것을 허용하지 않습니다.

한 가지 방법은 실제 인스턴스를 사용하는 것입니다.

static int AVAL = 1;

void f( int & x = AVAL ) {
   // stuff
} 

int main() {
     f();       // equivalent to f(AVAL);
}

그러나 이것은 실용적으로 매우 제한적입니다.


귀하의 답변에 대한 의견 중 하나에서 이미 언급되는 것입니다. 사용하려는 목적입니다.

virtual const ULONG Write(ULONG &State, bool sequence);
inline const ULONG Write()
{
  ULONG state;
  bool sequence = true;
  Write (state, sequence);
}

기능을 사용하면 추가적인 이점이 있습니다. 먼저 원하는 인수를 구입하세요.

class A {}; 
class B {}; 
class C {};

void foo (A const &, B const &, C const &);
void foo (B const &, C const &); // A defaulted
void foo (A const &, C const &); // B defaulted
void foo (C const &); // A & B defaulted etc...

오버로드를 피하는 파생 클래스의 가상 함수에 기본 인수를 재정의 할 수도 있습니다.

class Base {
public:
  virtual void f1 (int i = 0);  // default '0'

  virtual void f2 (int);
  inline void f2 () {
    f2(0);                      // equivalent to default of '0'
  }
};

class Derived : public Base{
public:
  virtual void f1 (int i = 10);  // default '10'

  using Base::f2;
  virtual void f2 (int);
};

void bar ()
{
  Derived d;
  Base & b (d);
  d.f1 ();   // '10' used
  b.f1 ();   // '0' used

  d.f2 ();   // f1(int) called with '0' 
  b.f2 ();   // f1(int) called with '0
}

상황을 만나는 상황은 생성자에 있습니다. 한 생성 기능을 다른 생성자에서 호출 할 수 있습니다.


구매를 제공하는 오래된 C 방법이 여전히 있습니다. 존재하지 않을 때 NULL 일 수있는 포인터 :

void write( int *optional = 0 ) {
    if (optional) *optional = 5;
}

이 작은 템플릿이 도움이 될 것입니다.

template<typename T> class ByRef {
public:
    ByRef() {
    }

    ByRef(const T value) : mValue(value) {
    }

    operator T&() const {
        return((T&)mValue);
    }

private:
    T mValue;
};

그러면 다음을 수행 할 수 있습니다.

virtual const ULONG Write(ULONG &State = ByRef<ULONG>(0), bool sequence = true);

참조로 인수를 전달하는 데는 두 가지 이유가 있습니다. (1) 성능 (이 경우 const 참조로 전달하려는 경우) 및 (2) 함수 내에서 인수 값을 변경할 수있는 기능이 필요하기 때문입니다.

나는 현대 건축에 서명되지 않은 장기를 전달하는 것이 당신을 너무 느리게 만드는 것이라고 매우 의심합니다. 그래서 나는 당신이 State메소드 내부의 값을 변경하려고한다고 가정합니다 . 컴파일러는 상수 0가 rvalue (오류 메시지에서 "non-lvalue")이고 변경할 수 없기 때문에 (오류 메시지에서) 변경할 수 없기 때문에 불평하고 있습니다 const.

간단히 말해, 전달 된 인수를 변경할 수있는 메서드를 원하지만 기본적으로 변경할 수없는 인수를 전달하려고합니다.

달리 말하면 비 const참조는 실제 변수를 참조해야합니다. 함수 시그니처 ( 0) 의 기본값 은 실제 변수가 아닙니다. 다음과 같은 문제가 발생합니다.

struct Foo {
    virtual ULONG Write(ULONG& State, bool sequence = true);
};

Foo f;
ULONG s = 5;
f.Write(s); // perfectly OK, because s is a real variable
f.Write(0); // compiler error, 0 is not a real variable
            // if the value of 0 were changed in the function,
            // I would have no way to refer to the new value

State메서드 내에서 실제로 변경하지 않으려 는 경우 간단히 const ULONG&. 그러나 당신은 그것으로부터 큰 성능 이점을 얻지 못할 것이므로 비 참조로 변경하는 것이 좋습니다 ULONG. 나는 당신이 이미를 반환하고 ULONG있음을 알고 있으며 그 값이 State필요한 수정 후의 값이라는 은밀한 의심을 가지고 있습니다 . 어떤 경우에는 단순히 메서드를 다음과 같이 선언합니다.

// returns value of State
virtual ULONG Write(ULONG State = 0, bool sequence = true);

물론, 나는 당신이 무엇을 쓰고 있는지, 어디에 있는지 잘 모르겠습니다. 그러나 그것은 또 다른 질문입니다.


함수 호출에 대한 매개 변수로 사용할 수없는 것과 같은 이유로 기본 매개 변수에 상수 리터럴을 사용할 수 없습니다. 참조 값에는 주소가 있어야하며 상수 참조 값은 필요하지 않습니다 (즉, r 값 또는 상수 리터럴 일 수 있음).

int* foo (int& i )
{
   return &i;
}

foo(0); // compiler error.

const int* bar ( const int& i )
{
   return &i;
}

bar(0); // ok.

기본 값에 주소가 있고 괜찮은지 확인하십시오.

int null_object = 0;

int Write(int &state = null_object, bool sequence = true)
{
   if( &state == &null_object )
   {
      // called with default paramter
      return sequence? 1: rand();
   }
   else
   {
      // called with user parameter
      state += sequence? 1: rand();
      return state;
   }
}

변수 또는 null 일 수있는 매개 변수가있는 경우이 패턴을 몇 번 사용했습니다. 일반적인 접근 방식은 사용자가 포인터를 전달하도록하는 것입니다. 값을 채우지 않으려면 NULL 포인터를 전달합니다. 나는 null 객체 접근을 좋아합니다. 수신자 코드를 끔찍하게 복잡하게 만들지 않고 발신자 생활을 더 쉽게 만듭니다.


아니요, 불가능합니다.

참조로 전달하면 함수가 매개 변수의 값을 변경할 수 있음을 의미합니다. 매개 변수가 호출자에 의해 제공되지 않고 기본 상수에서 오는 경우 변경해야하는 함수는 무엇입니까?


그 이유는 기본값이 상수로 평가되고 참조로 전달 된 값은 상수 참조로 선언하지 않는 한 변경 될 수 있어야하기 때문입니다.


또 다른 방법은 다음과 같습니다.

virtual const ULONG Write(ULONG &State, bool sequence = true);

// wrapper
const ULONG Write(bool sequence = true)
{
   ULONG dummy;
   return Write(dummy, sequence);
}

그러면 다음 호출이 가능합니다.

ULONG State;
object->Write(State, false); // sequence is false, "returns" State
object->Write(State); // assumes sequence = true, "returns" State
object->Write(false); // sequence is false, no "return"
object->Write(); // assumes sequence = true, no "return"

void f(const double& v = *(double*) NULL)
{
  if (&v == NULL)
    cout << "default" << endl;
  else
    cout << "other " << v << endl;
}

OO의 경우 ... 주어진 클래스에 "기본값"이 있다는 것은이 기본값 (값)이 부수적으로 선언되어야 함을 의미하며 다음은 기본 매개 변수로 사용될 수 있습니다. 예 :

class Pagination {
public:
    int currentPage;
    //...
    Pagination() {
        currentPage = 1;
        //...
    }
    // your Default Pagination
    static Pagination& Default() {
        static Pagination pag;
        return pag;
    }
};

당신의 방법에 ...

 shared_ptr<vector<Auditoria> > 
 findByFilter(Auditoria& audit, Pagination& pagination = Pagination::Default() ) {

이 솔루션은이 경우 "Global default Pagination"이 단일 "참조"값이기 때문에 매우 적합합니다. 또한 "gobal-level"구성 (예 : 사용자 페이지 매김 탐색 기본 설정 등)과 같이 런타임에 기본값을 변경할 수 있습니다.


State에 대한 const 한정자로 가능합니다.

virtual const ULONG Write(const ULONG &State = 0, bool sequence = true);

void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);

이것에 대한 다소 더러운 트릭도 있습니다.

virtual const ULONG Write(ULONG &&State = 0, bool sequence = true);

이 경우 다음과 std::move같이 호출해야합니다 .

ULONG val = 0;
Write(std::move(val));

이것은 단지 몇 가지 재미있는 해결 방법 일 뿐이며 실제 코드에서 사용하는 것은 전적으로 권장하지 않습니다!


이에 대한 해결 방법이 있습니다. 기본값에 대한 다음 예제를 참조하십시오 int&.

class Helper
{
public:
    int x;
    operator int&() { return x; }
};

// How to use it:
void foo(int &x = Helper())
{

}

bool, double... 와 같은 원하는 사소한 데이터 유형에 대해 수행 할 수 있습니다 .


virtual const ULONG Write (ULONG & State = 0, bool 시퀀스 = true);

대답은 매우 간단하고 설명하는 데 그다지 좋지는 않지만이 함수에서 수정 될 비 상수 매개 변수에 기본값을 전달하려면 다음과 같이 사용하는 것입니다.

virtual const ULONG Write(ULONG &State = *(ULONG*)0, bool sequence =
> true);

참고 URL : https://stackoverflow.com/questions/1059630/default-value-to-a-parameter-while-passing-by-reference-in-c

반응형