模板功能:混合逐个复制&通过按引用

时间:2014-02-09 22:52:21

标签: c++ templates pass-by-reference pass-by-value

我有一个模板函数,负责将模板值写入流。它看起来像这样:

template < typename T >
void Write( T value, std::ostream& stream, endianness_t endian );

我已经实现了基本类型的版本:int,uint,float等。 现在,如果我想编写一个更复杂的结构,比如一个std :: string,我就这样声明:

template<>
inline void Write( const std::string& value, std::ostream& stream, endianness_t endian ) { // Notice the reference
...
}

如果没有明确调用“pass-by-reference”版本,我就无法调用它:

Write( strValue, stream, LITTLE_ENDIAN ); // error : tries to call Write<std::string>, undefined
Write< const std::string& >( strValue, stream, LITTLE_ENDIAN ); // OK, Write<const std::string&> is properly defined

问题在于,它对于我想要做的事情来说太冗长了。

我的问题是:如何让编译器猜测我想要使用的版本是“传递引用”?

我是否必须更改模板函数以获取const引用?如果是这样,我是否可以专门研究原始类型的“pass-by-copy”?

3 个答案:

答案 0 :(得分:9)

您应该更喜欢重载模板专业化,这样做可以解决您的问题:

inline void Write( const std::string& value, std::ostream& stream, endianness_t endian ) {
    // ...
}

我还建议您返回并更改您为int提及的所有专业知识,并将内容更改为重载。

答案 1 :(得分:3)

不要为要使用的每种可能类型提供重载。这打破了首先使用通用代码的逻辑。话虽如此,为每种类型提供专业化的需求可能会指出这不是最成功的模板应用,更不用说搞乱功能模板专业化并不是最漂亮的选择as Sutter says

由于您需要在互斥类型(内置插件和非内置插件)之间进行逻辑分离,因此可以选择以下方法:

template<class T>
typename std::enable_if< std::is_fundamental<T>::value >::type foo_func(T arg)
{
    std::cout << "Call for built in types" << std::endl;
}
template<class T>
typename std::enable_if< !std::is_fundamental<T>::value >::type foo_func(T  const &arg)
{
    std::cout << "Call for non built in types" << std::endl;
}

在这里解释代码会发生什么:

1)std :: is_fundamental将在编译时返回false或true,具体取决于T是用户定义还是内置类型。

2)std :: enable_if将在第一种情况下“允许”声明 true 的功能模板,在第二种情况下使用 false ,因此没有解决问题的能力发生。

3)因此,当为内置类型调用foo_func时,将使用第一个版本,并且通过值传递T(int,float等)(对于内置函数更快)并且......你可以成像在另一种情况下会发生什么。

答案 2 :(得分:0)

您可以将通用模板更改为const ref:

template < typename T >
void Write( const T& value, std::ostream& stream, endianness_t endian );