[英]force a strongly typed enum to participate in template overload resolution
As per this question - template argument deduction with strongly-typed enumerations - it seems challenging - if not impossible - to get strongly typed enumerators to participate in overload resolution.根据这个问题 - 使用强类型枚举的模板参数推导- 似乎具有挑战性 - 如果不是不可能的话 - 让强类型枚举器参与重载决议。
if we have the following如果我们有以下
#include <string>
#include <iostream>
void ExternalFunction(const std::string& tag, int value)
{
std::cout << tag << " - (int) " << value << std::endl;
}
void ExternalFunction(const std::string& tag, double value)
{
std::cout << tag << " - (double) " << value << std::endl;
}
void ExternalFunction(const std::string& tag, const std::string& value)
{
std::cout << tag << " - (string) " << value << std::endl;
}
class Wrapper
{
public:
virtual void DoSomething() = 0;
};
template <typename variable_type>
class VariableWrapper : public Wrapper
{
public:
VariableWrapper(variable_type variable) : variable(variable) {}
void DoSomething() override
{
ExternalFunction("tag", variable);
}
variable_type& variable;
};
template <typename enumerator, typename convert_to_string>
class EnumWrapper : public VariableWrapper<enumerator>
{
public:
EnumWrapper(enumerator& variable, convert_to_string encoder) : VariableWrapper<enumerator>(variable), encoder(encoder) {}
void DoSomething() override
{
ExternalFunction("tag", encoder(VariableWrapper<enumerator>::variable));
}
convert_to_string encoder;
};
enum class StronglyTyped
{
A,
B,
C
};
int main()
{
StronglyTyped e = StronglyTyped::A;
Wrapper* wrapper = new EnumWrapper(e, [](StronglyTyped S)->std::string{return "Test";});
wrapper->DoSomething();
}
if we try to run this - http://coliru.stacked-crooked.com/a/d555c4e3300ab05d - we get the errors如果我们尝试运行它 - http://coliru.stacked-crooked.com/a/d555c4e3300ab05d - 我们会得到错误
main.cpp: In instantiation of 'void VariableWrapper<variable_type>::DoSomething() [with variable_type = StronglyTyped]':
main.cpp:31:14: required from here
main.cpp:33:29: error: no matching function for call to 'ExternalFunction(const char [4], StronglyTyped&)'
33 | ExternalFunction("tag", variable);
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
main.cpp:4:6: note: candidate: 'void ExternalFunction(const string&, int)'
4 | void ExternalFunction(const std::string& tag, int value)
| ^~~~~~~~~~~~~~~~
main.cpp:4:51: note: no known conversion for argument 2 from 'StronglyTyped' to 'int'
4 | void ExternalFunction(const std::string& tag, int value)
| ~~~~^~~~~
main.cpp:9:6: note: candidate: 'void ExternalFunction(const string&, double)'
9 | void ExternalFunction(const std::string& tag, double value)
| ^~~~~~~~~~~~~~~~
main.cpp:9:54: note: no known conversion for argument 2 from 'StronglyTyped' to 'double'
9 | void ExternalFunction(const std::string& tag, double value)
| ~~~~~~~^~~~~
main.cpp:14:6: note: candidate: 'void ExternalFunction(const string&, const string&)'
14 | void ExternalFunction(const std::string& tag, const std::string& value)
| ^~~~~~~~~~~~~~~~
main.cpp:14:66: note: no known conversion for argument 2 from 'StronglyTyped' to 'const string&' {aka 'const std::__cxx11::basic_string<char>&'}
14 | void ExternalFunction(const std::string& tag, const std::string& value)
| ~~~~~~~~~~~~~~~~~~~^~~~~
Is it possible to get the strongly typed enumerator to participate in the overload resolution?是否可以让强类型枚举器参与重载决议? I don't want to remove the strongly typing - which does remove this issue - as i will then have to use unique names between multiple enums我不想删除强类型 - 这确实删除了这个问题 - 因为我将不得不在多个枚举之间使用唯一的名称
EDIT: i have removed the std::to_string from the question and updated the code accordingly as it was incorrectly being focused on.编辑:我已经从问题中删除了 std::to_string 并相应地更新了代码,因为它被错误地关注。
You have written your code incorrectly.您编写的代码不正确。
OK, so EnumWrapper<>::DoSomething
overrides VariableWrapper<T>::DoSomething
.好的,所以EnumWrapper<>::DoSomething
覆盖了VariableWrapper<T>::DoSomething
。 So it won't be called by directly calling DoSomething
on any EnumWrapper
object.所以它不会通过在任何EnumWrapper
对象上直接调用DoSomething
来调用。
But that doesn't mean VariableWrapper<T>::DoSomething
doesn't exist .但这并不意味着VariableWrapper<T>::DoSomething
不存在。 It does exist, and you can still call it by a qualified call.它确实存在,您仍然可以通过合格的调用来调用它。 As such, when you instantiate VariableWrapper<T>
for some particular T
, the member functions of this template class must be valid.因此,当您为某个特定T
实例化VariableWrapper<T>
,此模板类的成员函数必须有效。
And VariableWrapper<T>::DoSomething
is not valid for any T
which cannot be used to call ExternalFunction
directly.并且VariableWrapper<T>::DoSomething
对任何不能用于直接调用ExternalFunction
T
无效。 This has nothing to do with enumerations specifically;这与具体的枚举无关; it's purely about how you wrote your function.这纯粹是关于你如何编写你的函数。
You should instead make EnumWrapper
not inherit from VariableWrapper
.您应该改为使EnumWrapper
不继承自VariableWrapper
。 They both can inherit from BaseWrapper
, but they have no business inheriting from one another.它们都可以从BaseWrapper
继承,但它们没有相互继承的业务。 Alternatively you could make ExternalFunction
itself a template that can resolve how to do whatever it is that it does for any given type.或者,您可以使ExternalFunction
本身成为一个模板,该模板可以解决如何为任何给定类型执行任何操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.