flu*_*mpb 1 c++ templates c++11
我不确定如何提出这个问题,因为我对模板使用的知识很浅,但这里什么都没有.
我有一个类,我想为所有数值提供一个函数模板,然后这个函数模板调用非模板版本,它需要一个std :: string,如下所示.
template< class T > void
add_to_header( const std::string &key, const T &val )
{
add_to_header( key, std::to_string( val ) );
}
virtual void
add_to_header( const header& header );
virtual void
add_to_header( const std::string &key, const std::string &val );
Run Code Online (Sandbox Code Playgroud)
这段代码编译得很干净,但是我失去了使用const char []进行调用的能力.
instance.add_to_header( "Example1", 4 ); // successful
instance.add_to_header( "Example2", std::string( "str val" ) ); // successful
instance.add_to_header( "Example3", "Not fun" ); // error - none of the 9 overloads could convert all the argument types
Run Code Online (Sandbox Code Playgroud)
解决这个问题的惯用方法是什么?
如果你在声明中指定add_to_header它需要能够调用to_string它的参数,那么模板重载将通过SFINAE消除:
void add_to_header( const std::string &key, const std::string &val );
template<typename T> auto add_to_header( const std::string &key, const T &val )
-> decltype(std::to_string(val), void()) // uses comma operator
{
add_to_header( key, std::to_string( val ) );
}
Run Code Online (Sandbox Code Playgroud)
请注意,非模板重载需要在模板主体定义的语法点处可见,以便主体内部的调用可以看到非模板重载.
使用C++ 14约束,我们可以用封装需求的约束替换typename T(或class T):
template<typename T> constexpr bool ToStringable() {
using namespace std;
void to_string(...);
return is_same<string, decltype(to_string(declval<T>()))>::value;
}
template<ToStringable T>
void add_to_header( const std::string &key, const T &val )
{
add_to_header( key, std::to_string( val ) );
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
219 次 |
| 最近记录: |