了解C ++成员函数模板专门化 [英] Understanding C++ member function template specialization

查看:112
本文介绍了了解C ++成员函数模板专门化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类:

  #pragma once 
#include< string&
#include< iostream>

class testclass
{
public:
template< class T> T item(const std :: string& key)
{
std :: cout< non-specialized \\\
;
return T();
}
};

对于项目方法,我想为字符串提供一个特殊化。我试着这样做(在testclass.cpp):

  #includetestclass.h
#include< iostream>

模板<> std :: string testclass :: item(const std :: string& key)
{
std :: cout< specialized\\\
;
return std :: reverse(key.begin(),key.end());
}

然后我尝试调用这样的函数:

  #include< iostream> 
#includetestclass.h

int main()
{
testclass t;
std :: string key =foo;
t.item< int>(key);
std :: string s = t.item< std :: string>(key);
std :: cout<< s < std :: endl;
}

但是,输出是

  $ ./a.out 
非专业化
非专业化
(空行)

我例外的是

  $。 /a.out 
非专业化
专业化
oof

我如何正确地这样做?我使用g ++ 4.5.2来编译程序。



编辑



解决方案是移动专业化的整个定义 item 到testclass.h(但不是类)。我在程序中有其他错误,例如不包括< algorithm> (用于反向),以及不正确地认为它将返回反向字符串。要实现例外的行为,.cpp文件留空,并且标题内容如下:

  #pragma once 
#include< string>
#include< iostream>
#include< algorithm>

class testclass
{
public:
template< class T> T item(const std :: string& key)
{
std :: cout< non-specialized \\\
;
return T();
}
};

模板<> std :: string testclass :: item(const std :: string& key)
{
std :: cout< specialized\\\
;
std :: string s = key;
std :: reverse(s.begin(),s.end());
return s;
}


解决方案

问题归结为常见的问题是在头文件中没有模板。当处理 main 时,编译器没有看到特殊化,它会为 std :: string 。这是对ODR的违反,因为现在在同一程序中有 std :: string 的两个不同的专门化,但编译器不需要诊断它。 p>

简单的解决方案是在头中声明/定义特殊化,以便编译器可以使用它,或者至少知道不从通用版本生成特化处理 main


I have the following class:

#pragma once
#include <string>
#include <iostream>

class testclass
{
public:
    template <class T> T item(const std::string& key)
    {
        std::cout << "non-specialized\n";
        return T();
    }
};

For the item method I would like to provide a specialization for strings. I try to do this the following way (in testclass.cpp):

#include "testclass.h"
#include <iostream>

template<> std::string testclass::item(const std::string& key)
{
    std::cout << "specialized\n";
    return std::reverse(key.begin(), key.end());
}

And then I try to call the function like this:

#include <iostream>
#include "testclass.h"

int main()
{
    testclass t;
    std::string key = "foo";
    t.item<int>(key);
    std::string s = t.item<std::string>(key);
    std::cout << s << std::endl;
}

However, the output is

$ ./a.out
non-specialized 
non-specialized
(empty line)

What I excepted was

$ ./a.out
non-specialized 
specialized
oof

How can I do this properly? I am using g++ 4.5.2 to compile the program.

Edit:

The solution is the move the whole definition of the specialization of item to testclass.h (but not into the class). I had other mistakes in the program, such as not including <algorithm> (for reverse), and incorrectly thinking that it would return the reversed string. To achieve the excepted behaviour, the .cpp file is left empty, and the header contents are the following:

#pragma once
#include <string>
#include <iostream>
#include <algorithm>

class testclass
{
    public:
        template <class T> T item(const std::string& key)
        {
            std::cout << "non-specialized\n";
            return T();
        }
};

template<> std::string testclass::item(const std::string& key)
{
    std::cout << "specialized\n";
    std::string s = key;
    std::reverse(s.begin(), s.end());
    return s;
}

解决方案

The problem boils down to the common problem of not having the templates in the header file. The compiler, when processing main does not see the specialization and it generates its own instantiation of the generic template for std::string. This is a violation of the ODR, as there are now 2 different specializations for std::string in the same program, but the compiler is not required to diagnose it.

The simple solution is to declare/define the specialization in the header so that the compiler can either use it, or at least will know not to generate the specialization from the generic version when processing main

这篇关于了解C ++成员函数模板专门化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆