T 与 SomeClass<T> 的模板函数重载决议
Template function overload resolution of T vs. SomeClass<T>
我想了解为什么 void handleParam(const Str& name, Table<T> value)
模板重载从未被实例化(注意下面的代码是说明性的)。我敢肯定它不起作用是有充分理由的,我只是想了解这个原因。我知道(并正在使用)使用中间模板化结构的解决方法。但是如果像下面这样的东西是可能的,它会大大简化我的代码。
class TypeHandler
{
public:
TypeHandler(OtherClass& bi) : _bi(bi) { }
template <typename T> void handleParam(const Str& name, Table<T> value)
{
// Never gets instantiated.
}
template <typename T> void handleParam(const Str& name, T value)
{
}
}
template<typename HandlerType>
void HandleParamValue::handleTab(DataBlock& data, HandlerType& handler) {
...
// Table of floats.
Table<float> tab;
handler.handleParam<Table<float>>(param_name, tab);
// etc.
...
}
template<typename HandlerType>
void ParamStore::Iterate(HandlerType& handler) {
for (...) {
...
if (is_table(type)) {
HandleParamValue::handleTab<HandlerType>(_datablock, handler);
}
else {
HandleParamValue::handle<HandlerType>(_datablock, handler);
}
}
}
// Kick the whole thing off.
TypeHandler handler(_some_instance);
_param_store->Iterate(handler);
原因似乎很简单:如果你写
handler.handleParam<Table<float>>(param_name, tab);
您明确指定 T = Table<float>
。所以使用 handleParam(const Str& name, T value)
。如果要使用handleParam(const Str& name, Table<T> value)
,需要指定T = float
:
handler.handleParam<float>(param_name, tab);
甚至
handler.handleParam(param_name, tab);
因为编译器会自动select最专业的版本。
我使用了以下代码进行测试:
#include <iostream>
#include <vector>
class TypeHandler
{
public:
template <typename T> void handleParam(const std::string& name, std::vector<T> value)
{
std::cout << "std::vector<T>\n";
}
template <typename T> void handleParam(const std::string& name, T value)
{
std::cout << "T\n";
}
};
template<typename HandlerType>
void handleTab(const std::string& name, HandlerType& handler) {
std::vector<float> tab;
handler.handleParam(name, tab);
}
int main()
{
TypeHandler t;
handleTab("dfds", t);
return 0;
}
如果不能充分反映您的问题,请在评论中说明。
我想了解为什么 void handleParam(const Str& name, Table<T> value)
模板重载从未被实例化(注意下面的代码是说明性的)。我敢肯定它不起作用是有充分理由的,我只是想了解这个原因。我知道(并正在使用)使用中间模板化结构的解决方法。但是如果像下面这样的东西是可能的,它会大大简化我的代码。
class TypeHandler
{
public:
TypeHandler(OtherClass& bi) : _bi(bi) { }
template <typename T> void handleParam(const Str& name, Table<T> value)
{
// Never gets instantiated.
}
template <typename T> void handleParam(const Str& name, T value)
{
}
}
template<typename HandlerType>
void HandleParamValue::handleTab(DataBlock& data, HandlerType& handler) {
...
// Table of floats.
Table<float> tab;
handler.handleParam<Table<float>>(param_name, tab);
// etc.
...
}
template<typename HandlerType>
void ParamStore::Iterate(HandlerType& handler) {
for (...) {
...
if (is_table(type)) {
HandleParamValue::handleTab<HandlerType>(_datablock, handler);
}
else {
HandleParamValue::handle<HandlerType>(_datablock, handler);
}
}
}
// Kick the whole thing off.
TypeHandler handler(_some_instance);
_param_store->Iterate(handler);
原因似乎很简单:如果你写
handler.handleParam<Table<float>>(param_name, tab);
您明确指定 T = Table<float>
。所以使用 handleParam(const Str& name, T value)
。如果要使用handleParam(const Str& name, Table<T> value)
,需要指定T = float
:
handler.handleParam<float>(param_name, tab);
甚至
handler.handleParam(param_name, tab);
因为编译器会自动select最专业的版本。
我使用了以下代码进行测试:
#include <iostream>
#include <vector>
class TypeHandler
{
public:
template <typename T> void handleParam(const std::string& name, std::vector<T> value)
{
std::cout << "std::vector<T>\n";
}
template <typename T> void handleParam(const std::string& name, T value)
{
std::cout << "T\n";
}
};
template<typename HandlerType>
void handleTab(const std::string& name, HandlerType& handler) {
std::vector<float> tab;
handler.handleParam(name, tab);
}
int main()
{
TypeHandler t;
handleTab("dfds", t);
return 0;
}
如果不能充分反映您的问题,请在评论中说明。