为什么这种显式模板专业化不起作用?

时间:2016-04-13 11:50:33

标签: c++ templates

来自此代码:

// Example program
#include <iostream>
#include <string>

struct Z { static const int z = 1; };
struct Y { static const int y = 2; };

template <typename A> struct TE { int foo(); int bar(); };

template <> int TE<Y>::bar() { return foo(); }
template <typename A> int TE<A>::bar() { return foo(); }

template <> int TE<Y>::foo() { return Y::y; }
template <typename A> int TE<A>::foo() { return A::z; }

template struct TE<Z>;
template struct TE<Y>;

int main()
{
    TE<Z> z;
    TE<Y> y;

    std::cout << z.bar() << std::endl;
    std::cout << y.bar() << std::endl;
    return 0;
}

出现此错误

21:28: error: specialization of 'int TE<A>::foo() [with A = Y]' after instantiation
 In instantiation of 'int TE<A>::foo() [with A = Y]':
13:12:   required from here
28:15: error: 'z' is not a member of 'Y'
 In member function 'int TE<A>::foo() [with A = Y]':
29:1: warning: control reaches end of non-void function [-Wreturn-type]

这些实现是在单独的cpp文件中完成的。并且结构位于标题中,典型的显式模板实例化。

为什么这样做

int TE<Y>::bar() { return foo(); }

尝试使用此

template <typename A> int TE<A>::foo() { return A::z; }

而不是

template <> int TE<Y>::foo() { return Y::y; }

2 个答案:

答案 0 :(得分:1)

http://en.cppreference.com/w/cpp/language/template_specialization

明确专门化只能出现在与主要模板相同的名称空间中,必须出现在非专业模板声明之后。

此外,您需要遵循单一定义规则(ODR)。所以通常你会在同一个标​​题中提供你的实现。

答案 1 :(得分:1)

问题是您的// connect to your database $mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db'); // build query and use an alias for the `MAX(employee_id)` // so you can easily use its name in the result set $sql = "SELECT MAX(employee_id) as max_empid FROM employees"; // Now we must execute this query $result = $mysqli->query($sql); // Now we must chech that the query worked if ( $result === FALSE ) { echo sprintf( 'Query Failed: %s<br>%s', $sql, $mysqli->error); exit; } // now we must read one of the rows from the result set // produced by the ->query() command. // In this case there of course there is only one result row $row = $result->fetch_object(); echo 'Id: ' . $row->max_empid; 专业化在foo被实例化时尚未知晓,因此中的bar {{1} } s引用foo基本模板。

正如第一条错误消息所示,当编译器进入bar专门化时,基本模板已经使用foo进行了实例化。
第二个错误是&#34;级联错误&#34;由于专业化失败,在盛大的C ++传统中。

如果重新排列定义,则可以:

Y