2017-03-15 57 views
0

我有一個簡單的原始類型的包裝工作:用戶定義的轉換操作符不上引用

template <typename T> 
class Scalar { 
public: 
    explicit Scalar(T value) : value{value} {} 

    Scalar(Scalar&& other) = default; 
    Scalar& operator=(Scalar&& other) = default; 
    Scalar(const Scalar& other) = default; 
    Scalar& operator=(const Scalar& other) = default; 

    template <typename U> 
    explicit operator Scalar<U>() { 
    return Scalar<U>{static_cast<U>(this->value)}; 
    } 

    inline T getValue() const noexcept { return this->value; } 
private: 
    T value; 
}; 

鑄造標量值效果很好,但不知何故,它失敗的引用,例如

auto a = Scalar<double>{2.54}; 
Scalar<int> b = static_cast<Scalar<int>>(a); // works 

const auto& c = a; 
Scalar<int> d = static_cast<Scalar<int>>(c); // fails 

這裏的編譯錯誤(在這裏可以http://rextester.com/GOPYU13091檢查),可能是什麼問題,這裏有什麼想法?

source_file.cpp: In function ‘int main()’: 
source_file.cpp:31:47: error: no matching function for call to ‘Scalar(const Scalar<double>&)’ 
    Scalar<int> d = static_cast<Scalar<int>>(c); 
              ^
source_file.cpp:12:3: note: candidate: Scalar<T>::Scalar(const Scalar<T>&) [with T = int] <near match> 
    Scalar(const Scalar& other) = default; 
^
source_file.cpp:12:3: note: conversion of argument 1 would be ill-formed: 
source_file.cpp:31:47: error: could not convert ‘c’ from ‘const Scalar<double>’ to ‘const Scalar<int>&’ 
    Scalar<int> d = static_cast<Scalar<int>>(c); 
              ^
source_file.cpp:10:3: note: candidate: Scalar<T>::Scalar(Scalar<T>&&) [with T = int] <near match> 
    Scalar(Scalar&& other) = default; 
^
source_file.cpp:10:3: note: conversion of argument 1 would be ill-formed: 
source_file.cpp:31:47: error: could not convert ‘c’ from ‘const Scalar<double>’ to ‘Scalar<int>&&’ 
    Scalar<int> d = static_cast<Scalar<int>>(c); 
              ^

回答

5

這是一個const VS非const問題,不是參考VS對象問題。

使用

auto& c = a; 
Scalar<int> d = static_cast<Scalar<int>>(c); 

爲我工作。

通過改變用戶定義的轉換操作符const成員函數

template <typename U> 
explicit operator Scalar<U>() const { 
    return Scalar<U>{static_cast<U>(this->value)}; 
} 

還確保了以下工作。

const auto& c = a; 
Scalar<int> d = static_cast<Scalar<int>>(c);