如何在成员函数中使用隐式类型转换?

马丁·德罗兹迪克(Martin Drozdik)

让我们考虑以下示例,这些示例说明了隐式类型转换 在哪些地方起作用以及在哪些地方不起作用

#include <iostream>
#include <vector>

struct Thingy
{
    void write()
    {
        std::cout << "x" << std::endl;
    }
};

struct Node
{
    Thingy a;
    int data;
    operator Thingy&(){return a;}
};

void f(Thingy thingy)
{
    thingy.write();
}

template <typename TIterator>
void f (TIterator begin, TIterator end)
{
    for (TIterator it = begin; it != end; ++it)
        it->write();
}

int main()
{
    std::vector<Node> vector(10);

    f(vector.begin(), vector.end());  // Doesn't compile
    f(vector[3]);                     // compiles
    vector[3].write();                // Doesn't compile
    return 0;
}

为什么会这样呢?

void Node::write(); 

不应与以下内容有根本区别:

void write(Node* this);

有什么方法可以使我的示例代码编译并运行?

编辑:

我了解为什么它不起作用的机制,我想了解其原理。为什么C ++标准委员会认为这是个坏主意?

皮埃尔·T。

这是行不通的,因为您在执行操作时从不要求编译器进行转换:

it->write();

我猜它应该与static_cast一起工作:

static_cast<Thingy&>(*it).write();

但我几乎不确定您应该简单地使用:

it->get_a().write();

就像其他人所说的那样,更好的方法是在Node中声明一个写方法。

隐式转换可能是邪恶的。

因为您不能更改f函数,所以应该包装迭代器,以便可以使用Boost来取消引用Thingy而不是Node的引用

#include <iostream>
#include <vector>
#include <boost/iterator/transform_iterator.hpp>
struct Thingy
{
    void write()
    {
        std::cout << "x" << std::endl;
    }
};

struct Node
{
    Thingy a;
    int data;
    operator Thingy&(){return a;}
};

void f(Thingy thingy)
{
    thingy.write();
}

template <typename TIterator>
void f (TIterator begin, TIterator end)
{
    for (TIterator it = begin; it != end; ++it)
        it->write();
}

struct Node2Thingy
{
  typedef Thingy& result_type;
  Thingy& operator()(Node& n) const { return n.a; }
};

int main()
{
    std::vector<Node> vector(10);

    f(boost::make_transform_iterator(vector.begin(), Node2Thingy()),
         boost::make_transform_iterator(vector.end(), Node2Thingy()));
    f(vector[3]);                     // compiles


    return 0;
}

在g ++ 4.8.1上工作(但肯定也在旧版本上工作)。

您试图通过添加“隐式”间接解决问题,但是在这种情况下,它不起作用。您可以通过添加显式间接解决它。

要回答您的问题,幕后没有哲理。这纯粹是一种机制,C ++使用在编译时解析的类型,因此一切在执行之前就具有其类型。您希望编译器如何猜测必须在Node上调用转换运算符。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在函数参数中强制执行类型并避免隐式转换?

如何在表达式树C#中使用隐式转换?

隐式类型转换的调用函数

C ++构造函数隐式类型转换

如何在Java中使用Scala隐式类

如何在 trait 中使用隐式方法

如何在c#中使用隐式

如何禁用常量的隐式类型转换?

无法使用接口隐式转换类型

防止在模板成员函数中隐式转换某些参数

如何理解最终覆盖器返回的类型被隐式转换为被调用的覆盖函数的返回类型?

如何在 TypeScript 中将数组类型隐式转换为元组类型?

如何在 JavaScript 中使用 Ramda 将这个嵌套的 if 函数转换为函数式编程

C ++:隐式成员函数

using语句中使用的类型必须隐式转换为'System.IDisposable'

“IEnumerator”:在 using 语句中使用的类型必须可隐式转换为“System.IDisposable”

在 MATLAB 中使用隐式数据类型进行正确的字符串转换

如何通过隐式转换获取可用成员的“符号”?

如何在成员函数中使用内置管道函数?

如何为参数中的隐式类型转换定义构造函数?

在类构造函数中使用时,Lambda不会隐式转换

如何在函数中使用任何类型?

C ++函数指针中的隐式类型转换?

具有模板化函数参数的隐式类型转换

如何在return语句中的“隐式”右值上进行类型转换

如何在通用设置中使用类型(=静态)成员

如何在扩展方法中使用泛型类型成员?

如何在Scala中隐式函数类型可以对效果进行建模?

如何在 Scala 中定义带有类型参数的隐式函数?