【问题标题】:idiomatic way for `class<T>` to `class<const T>` conversion operator`class<T>` 到 `class<const T>` 转换运算符的惯用方式
【发布时间】:2019-04-12 16:45:05
【问题描述】:

假设有一个模板类template &lt;class T&gt; myclass;

有没有一种惯用的方法可以将非常量 T 的对象转换为 const T 的对象?

基本上,我希望隐式发生以下转换:

void f(myclass<const int> x);

myclass<int> a;
f(a); // should compile

重要编辑:

看起来答案很琐碎(而且这个问题很愚蠢),但其中涉及到一些非常概念性的东西(至少对我而言)。

我的印象是我需要有条件地启用转换运算符,因为从 myclass&lt;const T&gt;myclass&lt;const T&gt; 的转换运算符没有任何意义,即当且仅当 @987654327 时我才需要声明转换运算符@ 是 const 合格。我期待编译器抱怨冗余转换运算符。

既然编译器对将类型X 转换为X 的标识转换运算符感到满意,那么赋值运算符或复制构造函数与标识转换运算符有什么区别?

MSVC 为身份转换运算符引发警告。这不是很好。

【问题讨论】:

    标签: c++ type-conversion operator-overloading idioms


    【解决方案1】:

    您可以使用返回 myclass 且类型为 const 限定的转换运算符来执行此操作。看起来像

    template<typename T>
    struct myclass
    {
        T foo;
        operator myclass<const T>() { return myclass<const T>{foo}; }
    };
    

    然后在

    int main() 
    { 
        myclass<int> a{42};
        f(a); // should compile
    }
    

    编译器会为你隐式调用它。


    如果您已经有一个 myclass&lt;const int&gt; 并将其传递给 f 您不必担心任何歧义,因为复制构造函数是完全匹配的,所以这就是所谓的。但是,如果您确实想在 T 已经是 const 时禁用转换运算符,那么您可以使用

    template<typename U = T, std::enable_if_t<!std::is_const_v<U>, bool> = true> 
    operator myclass<const U>() { return myclass<const U>{foo}; }
    

    【讨论】:

    • @Yashas 在这种情况下“const collapsing”发生了,你还能得到const Tmyclass&lt;const int&gt;operator myclass&lt;const T&gt; 会变成 operator myclass&lt;const const int&gt;,它会折叠成 operator myclass&lt;const int&gt;
    • 我有点困惑。从X 转换为X 的转换运算符没有多大意义?它必须是一个赋值运算符?
    • 我认为我需要有条件地启用转换运算符。
    • @Yashas "如果 T 已经被 const 限定了怎么办?" 如果foo is properly initialized,它将编译。
    • @Yashas 如果你已经有一个myclass&lt;const T&gt;,那么它就不会调用转换运算符,因为复制构造函数是完全匹配的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 2016-11-05
    相关资源
    最近更新 更多