2010-01-12 99 views
2

我有一个接口C++模板:防止基本模板的实例

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); 

我想改变

template<class T> 
T 
get(Source const &s, T const &d); 

其中有没有合理的基础模板,所以实际的基础定义是合法但无用的(return d;)。如果基础实例化,我能做些什么来强制编译时失败?这种情况是否有一种习惯解决方案?

+1

* base模板*是什么意思?另外请记住,功能模板不专门化,但过载。 – 2010-01-12 17:30:41

+0

“基本模板”与“专业化”相对 – 2010-01-12 18:14:45

+1

如果您不想定义“基本模板”,则无需向模板中添加模板。你最初的想法是为各种类型提供重载是正确的。 – 2010-01-12 19:00:04

回答

10

不要定义模板,只需声明它并定义三个特化。

template <typename T> 
T get(Source const &, T const &); 

template<> 
std::string get(Source const &s, std::string const &d) { 
    return d + s.stringval(); // or whatever 
} 

[编辑:删除有关重载的东西 - 只是一次,模板功能专业化确实似乎更好。谁会想要?]

+0

隐式转换是模板的原因 – 2010-01-12 17:44:11

+0

您的意思是调用者应该始终指定类型,而不是永远允许从参数中推断它吗? – 2010-01-12 18:00:53

+0

我的意思是我希望所选功能与实际类型完全匹配 – 2010-01-12 18:12:02

-1

将基类(t)声明为抽象,这样一个实例永远不能创建该类。

+0

这个问题是关于自由函数的,而不是类 – 2010-01-12 17:50:37

3

只是做

string get(source, string); 
int get (source, int); 
bool get(source, bool); 
+0

,它打开了一堆蠕虫,因为'bool'和'int'可以隐式地来回转换。 – 2010-01-12 17:48:20

+0

没问题,当正确的未转换过载可用时,编译器不会隐式转换它们。 – 2010-01-12 18:59:25

0

如果你愿意支付运行时多态性,你可以做到这一点...

template <typename T> 
class Interface 
{ 
    virtual T get(Source const &s, T const &d) = 0; 
}; 

class StringInterface : public Interface<std::string> 
{ 
    virtual std::string get(Source const& s, std::string const& d); 
}; 

// etc. 

因为你的基础是一个抽象类,你会得到如果您尝试直接实例化编译时失败。