我有一个界面
std::string
get_string(Source const &s, std::string const &d);
int
get_int(Source const &s, int const &d);
bool
get_bool(Source const &s, bool const &d);
Run Code Online (Sandbox Code Playgroud)
我想改成
template<class T>
T
get(Source const &s, T const &d);
Run Code Online (Sandbox Code Playgroud)
但是没有合理的基本模板,因此实际的基本定义是合法但无用的(return d;).如果基础实例化,我该怎么做才能强制编译时失败?对于这种情况,有没有惯用的解决方案?
我正在创建这样的函数:
void SetItem(const Key &key, const Value &value)
{
...
}
Run Code Online (Sandbox Code Playgroud)
键和值是某种类型.
在内部,我想像这样存储这对:
std::pair<const Key &, Value>
Run Code Online (Sandbox Code Playgroud)
所以这是我的问题:我需要强制Key实际上是一个l值,以便在函数退出时不会被清除(带有r值的不安全)
我可以为函数签名:
void SetItem(Key &key, const Value &value)
Run Code Online (Sandbox Code Playgroud)
这将阻止使用r值,但它不允许使用const键,我也不喜欢.
有没有办法让我在保留常量的同时强制Key成为l值?
我可以创建一个r值重载来防止它:
void SetItem(Key &&key, const Value &value)
{
[What do I put here?]
}
Run Code Online (Sandbox Code Playgroud)
谢谢
这个问题关系到这一个除了不是处理类型名称的模板参数,我想使用一个枚举非类型模板参数.
是否有可能只有特化的模板化(类成员函数),在非类型模板参数的情况下没有通用(工作)定义?
通过在类体中声明并仅提供特化,我能够使一个版本工作,但是任何使用非定义模板参数的误操作都不会产生错误,直到链接.更糟糕的是,缺失的符号隐含地指的是枚举的整数值而不是它的名称,所以它会让其他开发人员感到困惑.
我能够BOOST_STATIC_ASSERT从引用的问题中获取技术仅适用于typename模板参数.
此代码演示了这个想法.我不希望CAT-version调用编译:
#include <iostream>
#include <boost/static_assert.hpp>
// CLASS HEADER FILE:
struct foo_class
{
enum AllowedTypes { DOG, CAT };
template <AllowedTypes type>
void add_one_third( double bar ) const
{
BOOST_STATIC_ASSERT_MSG(sizeof(type)==0, "enum type not supported.");
}
};
// CLASS SOURCE FILE
template<>
void foo_class::add_one_third<foo_class::DOG>( double bar ) const
{
std::cout << "DOG specialization: " << bar + 1./3. << std::endl;
}
// USER SOURCE FILE
int main()
{
std::cout << "Template Specialization!\n\n"; …Run Code Online (Sandbox Code Playgroud)