标签: explicit-instantiation

如何使用extern模板

我一直在查看C++ 0x的N3291工作草案.我对extern模板感到好奇.第14.7.3节规定:

除了内联函数和类模板特化之外,显式实例化声明具有抑制它们引用的实体的隐式实例化的效果.

仅供参考:"明确的实例化声明"一词是标准的extern template.这已在第14.7.2节中定义.

这听起来像是在说如果你使用extern template std::vector<int>,那么做任何通常隐式实例化的事情std::vector<int>都不会这样做.

下一段更有趣:

如果实体是同一翻译单元中的显式实例化声明和显式实例化定义的主题,则该定义应遵循声明.作为显式实例化声明的主体并且以在否则将导致翻译单元中的隐式实例化(14.7.1)的方式中使用的实体应该是程序中某处的显式实例化定义的主题; 否则该程序格式错误,无需诊断.

仅供参考:术语"显式实例化定义"是这些事物的标准说法:template std::vector<int>.也就是说,没有了extern.

对我来说,这两件事说extern template防止了隐式实例化,但它并没有阻止显式实例化.所以,如果你这样做:

extern template std::vector<int>;
template std::vector<int>;
Run Code Online (Sandbox Code Playgroud)

第二行有效地否定了第一行,明确地做了第​​一行隐含发生的事情.

问题是:Visual Studio 2008似乎不同意.我想要使​​用的方法extern template是阻止用户隐式实例化某些常用模板,以便我可以在.cpp文件中显式实例化它们以减少编译时间.模板只会实例化一次.

问题是我必须在VS2008中围绕它们#ifdef.因为如果单个翻译单元看到extern和非extern版本,它将使extern版本获胜并且没有人会实例化它.然后是链接器错误.

所以,我的问题是:

  1. 根据C++ 0x,正确的行为是什么?应该extern template防止明确的实例化吗?
  2. 如果上一个问题的答案是它不应该,那么VS2008是错误的(被授予,它在规范之前写得很好,所以它不像是他们的错).VS2010如何处理这个问题?它是否实现了正确的extern template行为?

c++ templates visual-studio-2008 explicit-instantiation c++11

24
推荐指数
1
解决办法
1万
查看次数

如何在C++中为MPL向量的所有成员显式实例化模板?

请考虑以下头文件:

// Foo.h
class Foo {
    public: 
        template <typename T>
        void read(T& value);
};
Run Code Online (Sandbox Code Playgroud)

我想Foo::read在源文件中显式实例化成员函数模板,包括在boost::mpl::vector:

// Foo.cc
#include <boost/mpl/vector.hpp>
#include <boost/mpl/begin_end.hpp>
#include "Foo.h"

template <typename T>
void Foo::read(T& value) { /* do something */ }

typedef boost::mpl::vector<int, long, float> types;

// template Foo::read<int  >(int&);
// template Foo::read<long >(long&);
// template Foo::read<float>(float&);

// instantiate automatically ???
Run Code Online (Sandbox Code Playgroud)

可能吗?谢谢,丹尼尔.

编辑

我找到了一些解决方案 - 似乎Foo::read<T>在结构的构造函数中指定一个指针,然后声明该变量,导致实例化:

// intermezzo
template <typename T> struct Bar {
    Bar<T>() {
        void (Foo::*funPtr)(T&) = &Foo::read<T>; …
Run Code Online (Sandbox Code Playgroud)

c++ boost vector boost-mpl explicit-instantiation

20
推荐指数
1
解决办法
2066
查看次数

你什么时候使用模板显式实例化?

我刚刚阅读有关模板显式实例化的内容:

template struct MyStruct<long>;

它被描述为"非常罕见",所以它在什么情况下会有用?

c++ templates explicit-instantiation

19
推荐指数
3
解决办法
3227
查看次数

通过模板别名显式实例化类

是否可以通过模板别名显式实例化模板类?

如果是这样,怎么样?否则,有人可以指向讨论和决定反对的ISO文件吗?

template<class T>
struct A { };

/// Explicit instantiate A for int:
template struct A<int>;

/// Alias
template<class T>
using B = A<T>;

/// Explicitly instantiate A for double via alias B:
template struct B<double>;
/// error: elaborated type refers to a non-tag type
Run Code Online (Sandbox Code Playgroud)

不应该实例化,A<double>因为B<T>它只是一个不同的名称A<T>

templates explicit-instantiation c++11 template-aliases

12
推荐指数
1
解决办法
783
查看次数

模板类的模板化构造函数的显式实例化

我不确定它是否是Clang 3.2中的错误或违反C++ 03,但似乎模板类的模板化构造函数的显式实例化失败,但模板类的模板化成员函数的显式实例化成功.

例如,以下编译没有clang ++和g ++的问题:

template<typename T>
class Foo
{
public:
    template<typename S>
    void Bar( const Foo<S>& foo )
    { }
};
template class Foo<int>;
template class Foo<float>;

template void Foo<int>::Bar( const Foo<int>& foo );
template void Foo<int>::Bar( const Foo<float>& foo );
template void Foo<float>::Bar( const Foo<int>& foo );
template void Foo<float>::Bar( const Foo<float>& foo );
Run Code Online (Sandbox Code Playgroud)

而以下编译没有使用g ++警告但使用clang ++失败:

template<typename T>
class Foo
{
public:
    template<typename S>
    Foo( const Foo<S>& foo )
    { }
};
template class Foo<int>;
template …
Run Code Online (Sandbox Code Playgroud)

c++ clang explicit-instantiation clang++

11
推荐指数
1
解决办法
2711
查看次数

MSVC中的模板静态定义和显式特化实例化错误

我想知道为什么下面的代码在gcc中运行得很好

#include <iostream>
using namespace std;

template<typename T>
struct F { 
  static T const value;
};

template<> 
struct F<int> { // Specialization
    static int const value; 
}; 

template struct F<int>;

template<typename T>
T const F<T>::value = sizeof(T);

template<>
int const F<int>::value = 42;

int main() {

    struct F<int> ma;
    cout << ma.value;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/wvrurz

在MSVC 2012上我无法编译:

#include <iostream>
using namespace std;

template<typename T>
struct F {
  static T const value;
};

template<> 
struct F<int> { // Specialization
    static …
Run Code Online (Sandbox Code Playgroud)

c++ templates language-lawyer explicit-specialization explicit-instantiation

10
推荐指数
1
解决办法
2629
查看次数

如何明确地实例化基本模板类?

这个问题正在考虑模板类的明确实例化.

考虑B<T>从另一个模板类派生的模板类A<T>.我想明确地实例化,B<T>因为它的方法是从动态链接调用的,所以这些方法必须实例化,尽管它们不是在代码本身中调用的.当然,也会调用从中继承的方法A<T>,因此它们也必须实例化.

似乎C++在显式实例化模板类时不会实例化基类,如本问题所述: C++类模板的显式实例化是否实例化依赖基类? 例:

template<typename T>
class A{ void foo(){...} };

template<typename T>
class B : public A<T> {}

template class B<int>; // This will NOT instanciate A<int>::foo()!!!
Run Code Online (Sandbox Code Playgroud)

当然,我还需要实现所有基类.但是,我不想用此负担客户端代码,因为类层次结构可能非常深.考虑涉及10个或更多模板类的类层次结构.不应该敦促客户编写10个显式模板实例.这不仅仅是大量的写​​作; 当我向类层次结构引入更改时,它也会中断.

相反,我想以某种方式实现无论何时实现B<T>,那么它的所有基类都是如此.我尝试简单地在B本身中实现基类,如下所示:

template<typename T>
class B : public A<T> {
    template class A<T>; // Does not compile!
}
Run Code Online (Sandbox Code Playgroud)

但这不编译.还有其他方法可以实现这一目标吗?

c++ inheritance templates explicit-instantiation

9
推荐指数
1
解决办法
476
查看次数

Using `extern template` with third-party header-only library

I am using the glm library, which is a header-only collection of math utilities intended for 3D graphics. By using -ftime-trace on Clang and ClangBuildAnalyzer, I've noticed that a lot of time is being spent instantiating glm types:

**** Templates that took longest to instantiate:
 16872 ms: glm::vec<4, signed char, glm::packed_highp> (78 times, avg 216 ms)
 15675 ms: glm::vec<4, unsigned char, glm::packed_highp> (78 times, avg 200 ms)
 15578 ms: glm::vec<4, float, glm::packed_highp> (78 times, avg 199 ms)

... …
Run Code Online (Sandbox Code Playgroud)

c++ templates extern explicit-instantiation c++11

9
推荐指数
1
解决办法
587
查看次数

约束成员函数和显式模板实例化

G++ 和 Clang++ 同意以下代码段不是有效的 C++:

template<int dim, int rank>
struct Tensor {};

template<int dim>
double InnerProduct(Tensor<dim, 1> const &, Tensor<dim, 1> const &)
  { return 0.0; }

template<int dim>
double DoubleInnerProduct(Tensor<dim, 2> const &, Tensor<dim, 2> const &)
  { return 0.0; }

template<int dim, int rank>
class Field
{
private:
  static double Dot(Tensor<dim, rank> const &u, Tensor<dim, rank> const &v) requires (rank == 1)
    { return InnerProduct(u, v); }

  static double Dot(Tensor<dim, rank> const &u, Tensor<dim, rank> const &v) requires …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer explicit-instantiation c++-concepts c++20

9
推荐指数
1
解决办法
267
查看次数

C++20 概念:成员函数的部分有序约束的显式实例化

有效并输出“1”,因为函数的约束是部分排序的并且最受约束的重载获胜:

template<class T>
struct B {
    int f() requires std::same_as<T, int> {
        return 0;
    }
    int f() requires (std::same_as<T, int> && !std::same_as<T, char>) {
        return 1;
    }
};

int main() {
    std::cout << B<int>{}.f();
}
Run Code Online (Sandbox Code Playgroud)

也有效,因为显式实例化不会实例化不满足约束的成员函数:

template<class T>
struct B {
    int f() requires std::same_as<T, int> {
        return 0;
    }
    int f() requires (!std::same_as<T, int>) {
        return 1;
    }
};

template struct B<int>;
Run Code Online (Sandbox Code Playgroud)

那么这个应该怎么办呢?

template<class T>
struct B {
    int f() requires std::same_as<T, int> {
        return …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer explicit-instantiation c++-concepts c++20

8
推荐指数
1
解决办法
283
查看次数