我可以告诉 C++ 编译器如何自己进行任意类型转换吗? [英] Can I tell the C++ compiler how to do arbitrary type conversions itself?
问题描述
这个问题是另一个问题的后续:如何实现模板方法的自动类型转换?.
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屋!