템플릿 평가 중 암시 적 형식 변환 허용

ddcc

랩핑 된 객체가 생성, 액세스, 수정 및 소멸 될 때 계측 할 수있는 C ++ 유형용 래퍼 클래스를 작성 중입니다. 원본 코드에 대해이를 투명하게 만들기 위해 암시 적 변환 함수를 기본 형식에 다시 포함하지만 암시 적 변환이 평가되지 않기 때문에 래핑 된 개체가 템플릿에 직접 전달되면 실패합니다. 다음은이 문제를 보여주는 코드입니다.

#include <utility>

// simplified wrapper class
template <typename T>
class wrap {
    T t;
public:
    wrap() : t() {}
    wrap(const T& _t) : t(_t) {}
    wrap(T&& _t) : t(std::move(_t)) {}

    constexpr operator T&() { return t; }
    constexpr operator const T&() const { return t; }
};

// an example templated function
template <typename T>
bool is_same(const T& t1, const T& t2) { return t1 == t2;}

// second invocation fails due to template substitution failure
bool problem() {
    wrap<int> w(5);

    return is_same(static_cast<int>(w), 5) && is_same<>(w, 5);
}

static_cast각 템플릿 호출 사이트에서 래핑 된 변수를 수행하여 수동으로이 문제를 해결할 수 있지만 (첫 번째 호출에서 볼 수 있음) 대규모 코드 기반으로 작업하고 있기 때문에 확장이 잘되지 않습니다. 유사한 질문 은 각 템플릿 기능을 함수로 인라인하는 것을 제안 friend하지만,이를 위해서는 각 템플릿을 식별하고 복사해야하며 확장되지 않습니다.

(1) 템플릿 함수로이 변환 문제를 해결하거나 (2)이 문제없이 소스 수준에서 변수를 계측하는 방법에 대한 조언을 주시면 감사하겠습니다.

제프 개렛

예의 결함은 is_same. 동일한 유형의 두 인수가 필요하다고 선언합니다. 이는 필요하지 않은 요구 사항이며 해당 유형이 필요로하는를 갖도록 요구 ==하지 않습니다.

물론 그렇지 않으면 어렵고 장황하기 때문에 템플릿 함수를 제대로 제한하지 않는 C ++를 찾는 것이 일반적입니다. 저자는 실용적인 지름길을 택합니다. 즉, 인터페이스를 수정하는 접근 방식이 is_same아닙니까?

// C++17 version. Close to std::equal_to<>::operator().
template <typename T, typename U>
constexpr auto is_same(T&& t, U&& u)
    noexcept(noexcept(std::forward<T>(t) == std::forward<U>(u)))
    -> decltype(std::forward<T>(t) == std::forward<U>(u))
{
    return std::forward<T>(t) == std::forward<U>(u);
}

수정 된 is_same을 사용하면 코드가 작동합니다.

동일한 유형을 갖기 위해 두 개의 인수가 필요할 수있는 다른 예가 있습니다. 예를 들어 반환 유형이 인수 유형에 따라 다르고 반환 값은 다음 중 하나에서 올 수 있습니다.

template <typename T>
T& choose(bool choose_left, T& left, T& right) {
    return choose_left ? left : right;
}

이것은 훨씬 더 드뭅니다. 그러나 실제로 기본 또는 래퍼 유형을 사용할지 여부를 결정해야 할 수도 있습니다. 래퍼 유형에이 향상된 동작이 있고 조건부로 래핑 된 값 또는 기본 값을 사용하는 경우 기본 값을 래핑하여 향상된 동작을 계속 가져와야합니까, 아니면 향상 기능을 삭제합니까? 이 두 가지 행동 중 하나를 조용히 선택할 수 있다고해도, 그렇게하고 싶습니까?

그러나 static_cast<T>(...)예를 들어 접근자를 제공하면 라고 말하는 것보다 값을 더 쉽게 얻을 수 있습니다 .

// given wrap<int> w and int i
is_same(w.value(), 5);
choose_left(true, w.value(), i);

다른 몇 가지 중요한 의견이 있습니다.

wrap() : t() {}

이를 위해서는 T가 기본 구성 가능해야합니다. = default옳은 일을합니다.

wrap(const T& _t) : t(_t) {}
wrap(T&& _t) : t(std::move(_t)) {}

이것들은 명시 적이 지 않습니다. A T는 암시 적으로 a로 변환 할 수 wrap<T>있으며 그 반대의 경우도 마찬가지입니다. 이것은 C ++에서 잘 작동하지 않습니다. 예를 들어, 형식 true ? w : i이 올바르지 않습니다. 이로 인해 std::equality_comparable_with<int, wrap<int>>거짓 되며 is_same. 래퍼 형식은 명시 적으로 생성되어야하며 암시 적으로 기본 형식으로 변환 될 수 있습니다.

constexpr operator T&() { return t; }
constexpr operator const T&() const { return t; }

이것들은 ref-qualified가 아니므로 래퍼가 rvalue 인 경우에도 lvalue 참조를 반환합니다. 그것은 잘못된 것 같습니다.

마지막으로 구성 및 변환은 정확한 유형 만 고려합니다 T. 그러나 모든 장소 T가 사용되며 다른 유형에서 암시 적으로 변환 될 수 있습니다. 그리고 두 개의 변환은 C ++에서 허용되지 않습니다. 따라서 래퍼 유형의 경우 결정을 내릴 수 있으며 이는 종종 a T가 구성 가능한 모든 것에서 구성을 허용한다는 것을 의미 합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

템플릿 유형 추론의 암시 적 변환

분류에서Dev

데이터 형식 datetime에서 int 로의 암시 적 변환은 중첩 된 저장 프로 시저가 허용되지 않습니다.

분류에서Dev

암시 적으로 변환하는 가변 템플릿 클래스

분류에서Dev

템플릿 클래스에 대해 암시 적 형식 변환이 작동하지 않습니다.

분류에서Dev

암시 적 형식 변환 중에 최대 몇 개의 사용자 정의 변환 연산자를 암시 적으로 적용 할 수 있습니까?

분류에서Dev

데이터 형식 varchar에서 varbinary (max) 로의 암시 적 변환은 허용되지 않습니다. C #

분류에서Dev

템플릿 인수 대체가 실패하고 암시 적 변환이 수행되지 않음

분류에서Dev

Entity Framework 암시 적 형식 변환

분류에서Dev

std :: function 암시 적 형식 변환

분류에서Dev

분해 가능한 형식을 튜플로 암시 적으로 변환 할 수 없습니다.

분류에서Dev

적용 템플릿 적용 중 문제

분류에서Dev

xslt 적용 템플릿은 하나의 자식 유형을 무시합니다.

분류에서Dev

연산자에 대한 템플릿 클래스의 암시 적 변환 == ()

분류에서Dev

암시 적 변환이 템플릿 함수 매개 변수에 적용되지 않는 이유는 무엇입니까?

분류에서Dev

함수 포인터 유형의 템플릿 매개 변수가 모든 반환 유형의 함수를 허용하도록 허용

분류에서Dev

반환에 허용되지 않는 암시 적 변환

분류에서Dev

매개 변수로 유형 또는 템플릿을 허용하는 템플릿

분류에서Dev

클래스 템플릿의 추가 비 유형 템플릿 매개 변수를 사용하여 가변 메서드의 중첩 된 호출

분류에서Dev

가변 템플릿 유형

분류에서Dev

디스플레이 템플릿에서 선언 된 @model에 대한 암시 적 변환이있는 모델 사용

분류에서Dev

웹 양식의 템플릿 내용을 동적으로 변경

분류에서Dev

C ++에서 사용자 정의 형식에서 기본 형식으로 암시 적 변환

분류에서Dev

capture-default가 지정되지 않은 템플릿 람다의 const 변수를 암시 적으로 캡처

분류에서Dev

Symbol을 Integer, 중첩 형식으로 암시 적으로 변환하지 않습니다.

분류에서Dev

사용자 정의 유형을 사용한 암시 적 변환?

분류에서Dev

반환 값의 암시 적 형식 변환

분류에서Dev

가변 템플릿을 사용한 정적 상속

분류에서Dev

템플릿 형식 변환 연산자 =

분류에서Dev

스칼라가 맵을 튜플로 암시 적으로 변환

Related 관련 기사

  1. 1

    템플릿 유형 추론의 암시 적 변환

  2. 2

    데이터 형식 datetime에서 int 로의 암시 적 변환은 중첩 된 저장 프로 시저가 허용되지 않습니다.

  3. 3

    암시 적으로 변환하는 가변 템플릿 클래스

  4. 4

    템플릿 클래스에 대해 암시 적 형식 변환이 작동하지 않습니다.

  5. 5

    암시 적 형식 변환 중에 최대 몇 개의 사용자 정의 변환 연산자를 암시 적으로 적용 할 수 있습니까?

  6. 6

    데이터 형식 varchar에서 varbinary (max) 로의 암시 적 변환은 허용되지 않습니다. C #

  7. 7

    템플릿 인수 대체가 실패하고 암시 적 변환이 수행되지 않음

  8. 8

    Entity Framework 암시 적 형식 변환

  9. 9

    std :: function 암시 적 형식 변환

  10. 10

    분해 가능한 형식을 튜플로 암시 적으로 변환 할 수 없습니다.

  11. 11

    적용 템플릿 적용 중 문제

  12. 12

    xslt 적용 템플릿은 하나의 자식 유형을 무시합니다.

  13. 13

    연산자에 대한 템플릿 클래스의 암시 적 변환 == ()

  14. 14

    암시 적 변환이 템플릿 함수 매개 변수에 적용되지 않는 이유는 무엇입니까?

  15. 15

    함수 포인터 유형의 템플릿 매개 변수가 모든 반환 유형의 함수를 허용하도록 허용

  16. 16

    반환에 허용되지 않는 암시 적 변환

  17. 17

    매개 변수로 유형 또는 템플릿을 허용하는 템플릿

  18. 18

    클래스 템플릿의 추가 비 유형 템플릿 매개 변수를 사용하여 가변 메서드의 중첩 된 호출

  19. 19

    가변 템플릿 유형

  20. 20

    디스플레이 템플릿에서 선언 된 @model에 대한 암시 적 변환이있는 모델 사용

  21. 21

    웹 양식의 템플릿 내용을 동적으로 변경

  22. 22

    C ++에서 사용자 정의 형식에서 기본 형식으로 암시 적 변환

  23. 23

    capture-default가 지정되지 않은 템플릿 람다의 const 변수를 암시 적으로 캡처

  24. 24

    Symbol을 Integer, 중첩 형식으로 암시 적으로 변환하지 않습니다.

  25. 25

    사용자 정의 유형을 사용한 암시 적 변환?

  26. 26

    반환 값의 암시 적 형식 변환

  27. 27

    가변 템플릿을 사용한 정적 상속

  28. 28

    템플릿 형식 변환 연산자 =

  29. 29

    스칼라가 맵을 튜플로 암시 적으로 변환

뜨겁다태그

보관