我可以告诉 C++ 编译器如何自己进行任意类型转换吗? [英] Can I tell the C++ compiler how to do arbitrary type conversions itself?

查看:37
本文介绍了我可以告诉 C++ 编译器如何自己进行任意类型转换吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是另一个问题的后续:如何实现模板方法的自动类型转换?.

This question is a follow-up of another question: How to realize automatic type conversion for template methods?.

如果需要在模板方法中进行类型转换,我能以某种方式告诉编译器如何自己进行转换吗?

If a type conversion is needed within a template method, can I somehow tell the compiler how to do just that conversion itself?

我知道两种编码转换的可能性:

I know two possibilities to code the conversion:

  • 模板专业化
  • 提供转换重载(这是前一个问题的答案).

两者都很好,但可能需要编写样板代码.有没有办法只注入"类型转换代码,让编译器完成其余的工作?

Both are fine, but may require writing boilerplate code. Is there a way to "inject" just the type conversion code and let the compiler do the rest?

请看下面的示例代码.我需要提供从 std::string 到我的 Setting 类的转换.我怎么能告诉编译器如何转换它?

Please see the following example code. I need to provide a conversion from std::string to my Setting class. How could I tell the compiler how to convert it?

#include <string>
#include <vector>

class Setting
{
public:

    Setting(int)
    {
    }

    Setting(double)
    {
    }

    // It is not possible to provide a constructor taking std::string as argument,
    // because this code is within an external libary!!!
};

// Is is not possible to create an overload of this method, since in real life
// it is a class member function within an external library.
//
void storeSetting(const Setting&)
{
    // Storing setting...
}

// Template method that works with int, double and float, because Settings can
// be created from these basic types. But the method will not work
// for std::string, since there is no appropriate constructor.
template <typename Type>
void storeAll(std::vector<Type> elements)
{
    // A lot of lengthy storage preparation code
    // ...
    //

    // Final Storage
    for (const Type& element : elements)
    {
        storeSetting(element);
    }
}

// Solution by template specialization
template <>
void storeAll(std::vector<std::string> elements)
{
    // A lot of lengthy storage preparation code
    // ...
    //

    // Final Storage
    for (const std::string& element : elements)
    {
        storeSetting(stoi(element));
    }
}

// Solution by providing a conversion overload
//
// TODO: When containers are concerned, this is not handy.
// I dont have to repeat the "lengthy storage preparation code".
// On the other hand, the conversion code is lengthy boilerplate code itself.
// Is there another way to "inject" a user-defined type conversion?
void storeAll(std::vector<std::string> elements)
{
    std::vector<int> convertedElements;

    for (const std::string& element : elements)
    {
        convertedElements.push_back(stoi(element));
    }

    storeAll(convertedElements);
}

int main()
{
    std::vector<double> numbers1 = {1.0, 2.0, 3.0};
    std::vector<int> numbers2 = {2, 3, 4};
    std::vector<float> numbers3 = {3.0, 4.0, 5.0};

    storeAll(numbers1);
    storeAll(numbers2);
    storeAll(numbers3);

    std::vector<std::string> numbers4 = {"4", "5", "6"};
    storeAll(numbers4);

    return 0;
}

推荐答案

您不能在不属于您的类型之间添加隐式转换.

You cannot add implicit conversion between types you don't own.

但是您仍然可以创建为您进行转换的函数:

But you can still create function which does the conversion for you:

// The forwarding one for exisiting contructor
template <typename ... Ts>
auto makeSetting(const Ts&... args)
-> decltype(Setting{args...})
{
    return Setting{args...};
}

// Optionally, one to avoid unwanted copy constructor
const Setting& makeSetting(const Setting& s) { return s; }

// Your extra version
Setting makeSetting(const std::string& s)
{
    return Setting{std::stoi(s)};
}

然后在您的通用函数中:

Then in your generic function:

template <typename T>
void storeAll(std::vector<T> elements)
{
    // A lot of lengthy storage preparation code
    // ...

    // Final Storage
    for (const auto& element : elements)
    {
        storeSetting(makeSetting(element));
    }
}

这篇关于我可以告诉 C++ 编译器如何自己进行任意类型转换吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆