可变模板和混合的歧义错误
Ambiguity errors with variadic templates and mixins
我正在尝试创建一个回调注册类tat,它允许根据不同类型的字符串标识符注册回调。每个回调都具有签名void function( T val )
,其中T
是更改类型。
我创建了以下基本注册器类,它将字符串映射到函数。
#include <string>
#include <map>
#include <functional>
#include <cstdint>
#include <iostream>
using namespace std;
template< typename ValueType >
class BasicConfigCallbackRegistrar
{
public:
typedef ValueType value_type;
typedef BasicConfigCallbackRegistrar< value_type > type;
typedef function< void( const value_type ) > signature_type;
typedef map< string, signature_type > callback_map_type;
/// @brief constructor
BasicConfigCallbackRegistrar() : callbackMap_()
{
}
/// @brief register a create callback
/// @param nodePath the path identifying the node in config database
/// @param callback the callback to register
type& RegisterCallback( string nodePath, signature_type callback )
{
callbackMap_.insert( make_pair( move(nodePath), callback ) );
return *this;
}
void MakeCallback( const string& nodePath, value_type val )
{
// no checking assumes item is in map,
// do not do this in production code
auto iter = callbackMap_.find( nodePath );
iter->second( val );
}
private:
callback_map_type callbackMap_; ///< the callback map
};
然后,我使用可变模板为我想要支持的每种类型创建一个派生类。
template< typename... Types >
class ConfigCallbackRegistrar : public BasicConfigCallbackRegistrar<Types>...
{
public:
/// @brief constructor
ConfigCallbackRegistrar() : BasicConfigCallbackRegistrar<Types>()...
{}
};
然后将其类型定义为:
typedef ConfigCallbackRegistrar< uint32_t, string > CallbackRegistrar;
当我尝试按如下方式使用这个类时:
struct UintFtor
{
void operator()( uint32_t val )
{
cout << val << "n";
}
};
struct StringFtor
{
void operator ()( string val )
{
cout << val << "n";
}
};
int main()
{
CallbackRegistrar registrar{};
registrar.RegisterCallback( "SomeNode", UintFtor() );
registrar.RegisterCallback( "SomeNode", StringFtor() );
return 0;
}
不幸的是,当我试图编译它时,我得到了以下模糊性错误:
variadic-wrap.cpp: In function ‘int main()’:
variadic-wrap.cpp:87: error: request for member ‘RegisterCallback’ is ambiguous
variadic-wrap.cpp:27: error: candidates are: BasicConfigCallbackRegistrar<ValueType>& BasicConfigCallbackRegistrar<ValueType>::RegisterCallback(std::string, std::function<void(ValueType)>) [with ValueType = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]
variadic-wrap.cpp:27: error: BasicConfigCallbackRegistrar<ValueType>& BasicConfigCallbackRegistrar<ValueType>::RegisterCallback(std::string, std::function<void(ValueType)>) [with ValueType = unsigned int]
variadic-wrap.cpp:88: error: request for member ‘RegisterCallback’ is ambiguous
variadic-wrap.cpp:27: error: candidates are: BasicConfigCallbackRegistrar<ValueType>& BasicConfigCallbackRegistrar<ValueType>::RegisterCallback(std::string, std::function<void(ValueType)>) [with ValueType = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]
variadic-wrap.cpp:27: error: BasicConfigCallbackRegistrar<ValueType>& BasicConfigCallbackRegistrar<ValueType>::RegisterCallback(std::string, std::function<void(ValueType)>) [with ValueType = unsigned int]
对采用类型为value_type
的参数的MakeCallback
的调用也会产生相同的模糊性错误。
如果不将registrar
显式转换为基类类型,如何解决此问题?
我有一个解决方案。所需要的只是一个额外级别的间接性。在Derived类中,我添加了一个模板函数,它将分派到正确的基,如下所示:
template< typename... Types >
class ConfigCallbackRegistrar : public BasicConfigCallbackRegistrar<Types>...
{
typedef ConfigCallbackRegistrar<Types...> type;
public:
/// @brief constructor
ConfigCallbackRegistrar() : BasicConfigCallbackRegistrar<Types>()...
{}
template<typename T>
type& Register( string nodePath,
typename BasicConfigCallbackRegistrar<T>::signature_type callback )
{
BasicConfigCallbackRegistrar<T>::RegisterCallback( std::move(nodePath),
std::move(callback) );
return *this;
}
};
调用代码变为:
int main()
{
CallbackRegistrar registrar{};
registrar.Register<uint32_t>( "SomeNode", UintFtor() );
registrar.Register<string>( "SomeNode", StringFtor() );
return 0;
}
相关文章:
- C++17 中的歧义错误(模板模板参数和默认参数问题)
- 运算符的歧义错误<<自定义 std::ostream 子类中的重载
- 了解函数错误的歧义新声明
- 在C 中,静态成员函数是否继承了?如果是,为什么没有出现歧义错误
- 在 c++ 中使用重载的歧义错误
- 转换 - 错误 E2015,AnsiString(char) 和 AnsiString(short) 之间的歧义
- C++代码中出现歧义错误
- 可变模板和混合的歧义错误
- 错误:"std::copy "之间的重载歧义
- c++操作符string和char*导致歧义错误
- 使用c++ Builder 10 Seattle有很多歧义错误
- c++歧义符号错误
- 函数重载时出现歧义错误
- c++矢量错误,显示变量有歧义-我已经尝试了一切仍然没有希望
- 为什么这两个构造函数一起不会产生歧义错误?
- C2870符号歧义错误
- 由于模板函数声明中存在歧义而导致错误
- 与第三方头文件相关的C++Builder歧义错误
- 模板类相互使用会产生歧义错误
- 错误:对旧声明“double-round(double)”存在歧义