标签: conversion-operator

使用static_cast实现转换运算符

在这里提出的问题之后问这个问题.

这一点非常简单.假设你有两类这样的类:

template < class Derived >
class Base {
...
operator const Derived&() const {
    return static_cast< const Derived& >(*this);
  }
...
};

class Specialization : public Base<Specialization> {
...
};
Run Code Online (Sandbox Code Playgroud)

然后假设您有类似这样的类型转换:

template < class T >
functionCall( const Base<T>& param) {
  const T & val(param);
  ...
}
Run Code Online (Sandbox Code Playgroud)

问题是:这种转换的标准符合行为应该是什么?

它是否应该相同const T & val(static_cast<const T &> (param) )或应该递归迭代直到堆栈溢出?请注意,我获得了第一个使用GNU编译的行为g++,第二个使用Intel编译icpc.

我已经试图查看标准(关于static_cast的第5.9节和关于转换的第12.3节),但由于我缺乏经验,我无法找到答案.

我非常感谢任何花时间帮助我解决这个问题的人.

c++ standards crtp static-cast conversion-operator

7
推荐指数
1
解决办法
999
查看次数

由于有两种方法可以在C++中定义转换,当同一转换有两种可能性时,它们如何相互作用?

我只是想澄清C++是如何工作的,这不是关于解决我的代码中的特定问题.

在C++中,您可以说类型A应该以两种不同的方式隐式转换为类型B.

如果您是A的作者,可以在A中添加这样的内容:

operator B() {
   // code
}
Run Code Online (Sandbox Code Playgroud)

如果您是B的作者,可以向B添加这样的内容:

B(const A &a) {
    // code
}
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,其中任何一个都将允许A隐式转换为B.所以,如果两个都被定义使用哪一个?这甚至是允许的吗?

注意:我知道您可能永远不会遇到这种情况.您可以使构造函数显式,也可以只使用两者中的一个.我只是想知道C++规范说的是什么,我不知道如何看待它.

c++ conversion-operator implicit-conversion

7
推荐指数
1
解决办法
126
查看次数

C++ 中的重载函数和多个转换运算符歧义,编译器不同意

在下面的程序中 structS提供了两个转换运算符: indouble和 in long long int。然后一个类型的对象S被传递给一个函数f,重载为floatand double

struct S {
    operator double() { return 3; }
    operator long long int() { return 4; }
};

void f( double ) {}
void f( float ) {}

int main() {
    S s;
    f( s );
}
Run Code Online (Sandbox Code Playgroud)

MSVC 编译器可以正常接受程序,并选择f( double )重载。f然而,GCC 和 Clang 都发现, demo的调用存在歧义:https: //gcc.godbolt.org/z/5csd5dfYz

看来MSVC在这里是对的,因为转换: operator long long int()->f( float )不是提升。这是错的吗? …

c++ overloading conversion-operator language-lawyer overload-resolution

7
推荐指数
1
解决办法
181
查看次数

显式复制构造函数或隐式参数值

我最近阅读(并且遗憾地忘记了在哪里),编写operator =的最佳方法是这样的:

foo &operator=(foo other)
{
    swap(*this, other);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

而不是这个:

foo &operator=(const foo &other)
{
    foo copy(other);
    swap(*this, copy);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

我们的想法是,如果使用rvalue调用operator =,则第一个版本可以优化复制的构造.因此,当使用rvalue调用时,第一个版本更快,当使用左值调用时,这两个版本是等效的.

我很好奇其他人对此的看法?由于缺乏明确性,人们会避免使用第一个版本吗?我是否正确,第一个版本可以更好,永远不会更糟?

c++ parameters optimization operators conversion-operator

6
推荐指数
1
解决办法
1589
查看次数

为什么我不能阻止不受欢迎的 C 风格强制转换来编译?

有一个我无法阻止编译的不受欢迎的 C 样式转换。不需要的强制转换执行从某个类的对象到某个其他类的非常量引用的 C 样式转换。类是不相关的。同时,我喜欢支持从同一个类的对象到 const 引用的 C 风格转换。我正在提供一个公共转换运算符来支持理想的演员阵容。在这种情况下,似乎无法阻止不受欢迎的演员。
对非常量引用的转换无法构建(“Sandbox::B::operator Sandbox::A &() ”(在第 30 行声明)不可访问*),不幸的是,转换为 const 引用要么失败错误:多个从“Sandbox::B”到“const Sandbox::A”的转换函数适用:函数“Sandbox::B::operator const Sandbox::A &()”函数“Sandbox::B::运算符沙箱::A &()" ):

#include <iostream>
#include <string>
#include <cstdlib>

namespace Sandbox {
    class A {
    public:
        A (int i) : _x (i) { }
    private:
        int _x;
    };

    class B {
    public:
        B (const char* m) : _m (m), _a (std::atoi (m)) { }

        /*
         * This one shall be supported.
         */ 
        operator const A& () …
Run Code Online (Sandbox Code Playgroud)

c++ standards casting conversion-operator

6
推荐指数
1
解决办法
1581
查看次数

运算符 T&amp;() 还是运算符 T()?

在定义转换运算符时,定义有什么好处吗?

operator T() const;
Run Code Online (Sandbox Code Playgroud)

超过

operator T&();
operator const T&() const;
Run Code Online (Sandbox Code Playgroud)

假设我不关心返回值而不是引用的潜在性能提升。

c++ reference conversion-operator

6
推荐指数
1
解决办法
6976
查看次数

模板转换运算符的模糊分辨率

我不得不做类似的代码:

#include <type_traits>

template<typename S>
struct probe {
    template<typename T, typename U = S, std::enable_if_t<
        std::is_same<T&, U>::value &&
        !std::is_const<T>::value, int> = 0>
    operator T& () const;

    template<typename T, typename U = S&&, std::enable_if_t<
        std::is_same<T&&, U>::value &&
        !std::is_const<T>::value, int> = 0>
    operator T&& ();

    template<typename T, typename U = S, std::enable_if_t<
        std::is_same<T const&, U>::value, int> = 0>
    operator T const& () const;

    template<typename T, typename U = S&&, std::enable_if_t<
        std::is_same<T const&&, U>::value, int> = 0>
    operator T const&& () const;
}; …
Run Code Online (Sandbox Code Playgroud)

c++ templates conversion-operator language-lawyer

6
推荐指数
1
解决办法
136
查看次数

“歧义转换顺序”-此概念的目的是什么?

在N4659中16.3.3.1隐式转换序列

10如果存在几个不同的转换序列,每个转换序列都将自变量转换为参数类型,则与参数关联的隐式转换序列被定义为唯一的转换序列,称为歧义转换序列。为了对16.3.3.2中所述的隐式转换序列进行排名,歧义转换序列被视为与其他任何用户定义的转换序列都没有区别的用户定义的转换序列[注意:此规则可防止函数变为非-viable,因为其参数之一的转换顺序不明确。]如果选择使用歧义转换顺序的函数作为最佳可行函数,则该调用将格式错误,因为该调用中参数之一的转换是模棱两可的。

(当前草案的相应部分为12.3.3.1

该规则的预期目的是什么,以及引入的歧义转换序列的概念是什么?

文本中提供的注释指出,此规则的目的是“防止功能由于其参数之一的转换顺序不明确而变得不可行 ”。嗯...这实际上是指什么?可行功能的概念在文档的前面部分中定义。它根本不取决于转换的歧义性(每个参数的转换必须存在,但不必明确)。而且似乎没有提供可行的功能以某种方式在以后“变得不可行”的规定(既不是出于某种模棱两可,也不是因为其他原因)。列举了可行的功能,它们相互竞争,成为“最佳”如果有一个“获胜者”,则解决方案成功。在此过程中的任何时候,可行的功能都可能(或需要)变成不可行的功能。

上述段落中提供的示例不是很有启发性(即尚不清楚上述规则在该示例中扮演什么角色)。


这个简单的例子最初引发了这个问题

struct S
{
  operator int() const { return 0; };
  operator long() const { return 0; };
};

void foo(int) {}

int main()
{
  S s;
  foo(s);
}
Run Code Online (Sandbox Code Playgroud)

让我们在这里机械地应用上述规则。foo是可行的功能。从参数类型S到参数类型有两个隐式转换序列intS -> intS -> long -> int。这意味着,根据上述规则,我们必须将它们“打包”成单个模糊的转换序列。然后我们得出结论,这foo最好的可行功能。然后我们发现它使用了我们不明确的转换序列。因此,根据上述规则,代码格式错误。

这似乎没有任何意义。这里的自然期望是,S …

c++ conversion-operator language-lawyer overload-resolution implicit-conversion

6
推荐指数
1
解决办法
146
查看次数

MS VC ++上直接和副本初始化的不同行为(使用用户定义的转换运算符)

下面的代码编译罚款克++ 9.1铛8.0.0(编译标志是-std=c++17 -Wall -Wextra -Werror -pedantic-errors),但不与MSVC 19.22(编译标志是/std:c++17 /permissive-):

struct X{};

struct Bar
{
    Bar() = default;

    Bar(X){}
};

struct Foo
{
    operator X() const
    {
        return X{};
    }

    operator Bar() const
    {
        return Bar{};
    }
};

int main()
{
    Foo foo;
    [[maybe_unused]]Bar b1 = foo; // OK
    [[maybe_unused]]Bar b2(foo);  // failed
}
Run Code Online (Sandbox Code Playgroud)

MSVC编译错误:

<source>(27): error C2668: 'Bar::Bar': ambiguous call to overloaded function
<source>(8): note: could be 'Bar::Bar(Bar …
Run Code Online (Sandbox Code Playgroud)

c++ initialization conversion-operator language-lawyer c++17

6
推荐指数
1
解决办法
85
查看次数

在C ++中重载运算符时,为什么T *优于bool?

我有一个包装器类,其行为应类似于指针。我已经过载operator T*operator bool。布尔进行了一些额外的验证。我尝试在if中使用该对象,但我注意到该operator T*对象称为和bool。有人可以解释我为什么吗?是在标准中以某种方式指定的吗?我在MSVC,clang和gcc中测试了以下示例代码,它们都调用operator T*。另外,根据我在此页面上阅读的内容(https://en.cppreference.com/w/cpp/language/implicit_conversion),if应该尝试转换为bool

#include <stdio.h>

class MyClass
{
public:
    MyClass(int i)
        : m(i)
    {}

    operator bool() const
    {
        printf("operator bool()\n");
        return m;
    }

    operator int* ()
    {
        printf("operator int* ()\n");
        return &m;
    }

private:
    int m;
};

int main()
{
    MyClass a(5);
    MyClass b(0);

    if (a)
        printf("a is true\n");
    else
        printf("a is false\n");

    if (b)
        printf("b is true\n");
    else
        printf("b is false\n");

    return 0; …
Run Code Online (Sandbox Code Playgroud)

c++ class operator-overloading conversion-operator implicit-conversion

6
推荐指数
1
解决办法
266
查看次数