在模板实例化和外部模板声明中使用 typedef

using typedef in template instantiation and extern template declaration

extern template declarationexplicit template instantiation时,有两种情况让我感到困惑typedef

为了说明两者,请参见下面的 2 个示例代码片段。

考虑以下示例(案例 1)

// suppose following code in some cpp file    
template <typename T>
    struct example
{
    T value;
};

// valid typedefs
typedef example<int> int_example;
typedef example<std::string> string_example;

// explicit instantiation using above typedefs
template class int_example; // -> compile time error
template class string_example; // -> compile time error

// instead we need to use type names
template class example<int>; // -> OK
template class example<std::string>; // -> OK

// QUESTION 1: Why does this work however? is this valid code?
typedef std::string type_string;
template class example<type_string>;

为什么 template class example<type_string> 与 typedef 一起使用?为什么它有效而 template class string_example 无效?

考虑以下示例(案例 2)

// suppose following code is in some header file
template <typename T>
struct example
{
    T value;
};

// valid typedefs
typedef std::string type_string;
typedef example<type_string> string_example;

// Explicit instantiation declaration
// QUESTION 2: Is this valid code? if not why not?
extern template string_example; // -> at least this compiles, but is it OK?

正如上面评论中所质疑的那样,在 extern template declaration 中使用 typedef 是否有效,就像上面的例子一样,为什么这个编译不像 Case1 where它没有。

我读过类似的案例,但 none 给出了上述 2 个问题的详细答案。非常感谢详细的阐述!

template class int_example;

不合法。来自 C++11 标准:

14.7.2 Explicit instantiation

2 The syntax for explicit instantiation is:

explicit-instantiation:
externopt template declaration

There are two forms of explicit instantiation: an explicit instantiation definition and an explicit instantiation declaration. An explicit instantiation declaration begins with the extern keyword.

3 If the explicit instantiation is for a class or member class, the elaborated-type-specifier in the declaration shall include a simple-template-id.

simple-template-id 在第 A.12 模板 中定义为:

simple-template-id:
template-name < template-argument-listopt >

int_example 不符合 simple-template-id.
example<int> 确实符合 simple-template-id.

然而,按照这个逻辑,

extern template string_example;

也不合法。我不知道它对你有什么用。当我尝试在 g++ 4.9.3 中编译这样一行时出现以下错误。

socc.cc:15:31: error: expected unqualified-id before ‘;’ token
 extern template string_example; // -> compile time error