2

考虑以下我的代码的简化版本。我有一个模板类A、一个模板函数和一个专门用于处理诸如orFill之类的基本类型的函数,以及另一个可以处理的专门化:intcharA

#include <sstream>
#include <string>
#include <iostream>

template<size_t C>
class A
{
public:
    A & operator=(std::string v) { 
        data[0] ='a';
        return *this; 
    }
    char data[C];
};

template<typename T> T Fill(std::string value, T default_value);

// Specialization for A<C>
template<size_t C>
A<C> Fill(std::string value, A<C> default_value) 
{
    if (value.empty())
        return default_value;
    A<C> result;
    result = value;
    return result;
}

// Specialization for int, double, char, etc
template<typename T>
T Fill(std::string value, T default_value)
{   
    if (value.empty())
        return default_value;

    T result;
    std::istringstream(value) >> result;
    return result;
}

void main()
{
    int abc = Fill(/*Get a string somehow*/"123", 0); // OK

    A<10> def;
    def = std::string("111");
    A<10> a;
    a = Fill(/*Get a string somehow*/"abc", def);     // OK
}

虽然我很惊讶编译器设法将参数与正确的模板特化相匹配,但这工作得很好。

问题出在一些typedef易于使用的 s 上A<x>。这是一个简化版本:

typedef A<12> A12;
...
A<12> def12;
def12 = std::string("12");

A12 a12;
a12 = Fill(/*Get a string somehow*/"xyz", def12);       // Not OK !

编译器没有检测到该类型A12实际上是A<12>并且使用了错误的函数特化,该函数无法编译,因为 istringstream 无法将 o 解析perator>>A.

我怎样才能让它使用正确的模板专业化?

4

3 回答 3

4

模板特化不是通过您将返回值分配到的位置来推断的。您必须显式实例化正确的版本:

a12 = Fill<A<12> >("xyz", def);

(或者你需要的任何东西......)

于 2011-05-19T15:40:55.823 回答
1
typedef A<12> A12;
...
A12 a12;
a12 = Fill(/*Get a string somehow*/"xyz", def);       // Not OK !

在此示例中,您没有向我们展示def. 假设它和前面的例子一样,即A<10>,这肯定会失败。

在您的模板中,第二个参数的类型必须与返回类型匹配。尝试这个:

typedef A<12> A12;
...
A12 a12;
A12 def12;
a12 = Fill(/*Get a string somehow*/"xyz", def12);       // OK !
于 2011-05-19T15:51:40.097 回答
0

编译器没有检测到类型 A12 实际上是 A<12> 并且使用了错误的函数特化

实际上,由于您传递A<12> def;了示例(错误?),因此应该选择正确的重载(请参阅我对问题的评论)。您将结果分配给的事实A12 a;不应影响重载解决方案。

如果您的意思相反(传递A12和分配给任何东西),那么这可能是编译器的缺陷。这在这里正常工作。

于 2011-05-19T17:54:00.563 回答