标签: specialization

暧昧的模板怪异

我有以下代码(抱歉大代码块,但我不能再缩小它)

template <bool B>
struct enable_if_c {
      typedef void type;
};

template <>
struct enable_if_c<false> {};

template <class Cond>
struct enable_if : public enable_if_c<Cond::value> {};

template <typename X>
struct Base { enum { value = 1 }; };

template <typename X, typename Y=Base<X>, typename Z=void>
struct Foo;

template <typename X>
struct Foo<X, Base<X>, void> { enum { value = 0 }; };

template <typename X, typename Y>
struct Foo<X, Y, typename enable_if<Y>::type > { enum { value = 1 }; …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates specialization

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

C++模板构造函数的特化

我有一个模板化的类A <T,int>和两个typedef A <string,20>和A <string,30>.如何覆盖A <string,20>的构造函数?以下不起作用:

template <typename T, int M> class A;
typedef  A<std::string, 20> one_type;
typedef  A<std::string, 30> second_type;


template <typename T, int M>
class A {
public:
  A(int m) {test= (m>M);}

  bool test;

};


template<>
one_type::one_type() { cerr << "One type" << endl;}
Run Code Online (Sandbox Code Playgroud)

我希望类A <std :: string,20>做一些其他类没有的东西.如何在不更改构造函数的情况下执行此操作A:A(int)?

c++ templates constructor specialization

8
推荐指数
4
解决办法
2万
查看次数

类表继承与非规范化

我正在尝试建模专业化/泛化,倾向于使用类表继承(请参阅此答案).

但是,我的同事有维护和性能方面的问题,因为同一个表中会有很多(50+)个重叠的特化.他的建议是创建一个包含以下列的表:

  • 参考一般表格
  • 引用维护特化类型的表
  • 引用维护属性值的表

这样,所有属性都保存在一个表中,并且可以通过特化列进行过滤.我不知道这个设计叫什么,但我担心它与EAV有某种关系......

我主要担心的是修改异常现象,但除此之外,我没有看到任何理由这是一个坏主意.一种解决方案明显优于另一种解决方案,还是我们应该选择一种并继续前进?

database-design relational-database specialization

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

如何专门化低级函数以提高性能,同时保持高级函数的多态性?

我从我的生产项目中提取了以下最小示例。我的机器学习项目由线性代数库、深度学习库和应用程序组成。

线性代数库包含一个基于可存储向量的矩阵模块:

module Matrix where

import Data.Vector.Storable hiding (sum)

data Matrix a = Matrix { rows :: Int, cols :: Int, items :: Vector a } deriving (Eq, Show, Read)

item :: Storable a => Int -> Int -> Matrix a -> a
item i j m = unsafeIndex (items m) $ i * cols m + j

multiply :: Storable a => Num a => Matrix a -> Matrix a -> Matrix a
multiply a b = Matrix (rows …
Run Code Online (Sandbox Code Playgroud)

performance haskell specialization

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

部分类模板专业化是这个设计问题的答案吗?

假设您有一个班级,他们的工作就是连接到远程服务器.我想抽象这个类来提供两个版本,一个通过UDP连接,另一个通过TCP连接.我想构建最精简的运行时代码,而不是使用多态,我正在考虑模板.这是我想象的,但我不确定这是最好的方法:

class udp {};
class tcp {};

template<class T,typename X>
class service
{
private:
  // Make this private so this non specialized version can't be used
   service();
};

template<typename X>
class service<udp, X>
{
private:
   udp _udp;
   X _x;
};

template<typename X>
class service<tcp, X>
{
private:
   tcp _tcp;
   X _x;
};
Run Code Online (Sandbox Code Playgroud)

因此最终的好处是T的通用性仍然可用,但设置UDP或TCP连接所需的非常不同的代码已经过专门化.我想你可以将它们放在一个类中,或者提供另一个类,它遵循一些纯虚拟接口来设置网络连接,比如IConnectionManager.

但这确实留下了通用T的代码问题,现在必须在两个专用版本中编写和维护,它们最终都是相同的.如何最好地解决这个问题?我有一种感觉,我认为这一切都错了.

c++ oop templates specialization

7
推荐指数
2
解决办法
3865
查看次数

模板类的模板特化

我想专门研究以下成员函数:

class foo {
    template<typename T>
    T get() const;
};
Run Code Online (Sandbox Code Playgroud)

对于bar依赖于模板的其他类.

例如,我想barstd::pair有一些模板参数,这样的事情:

template<>
std::pair<T1,T2> foo::get() const
{
    T1 x=...;
    T2 y=...;
    return std::pair<T1,T2>(x,y);
}
Run Code Online (Sandbox Code Playgroud)

T1和T2也是模板.如何才能做到这一点?据我所知,它应该是可能的.

所以现在我可以打电话:

some_foo.get<std::pair<int,double> >();
Run Code Online (Sandbox Code Playgroud)

完整/最终答案:

template<typename T> struct traits;
class foo {
    template<typename T>
    T get() const
    {
       return traits<T>::get(*this); 
    }
};

template<typename T>
struct traits {
    static T get(foo &f)
    {
        return f.get<T>();
    }
};

template<typename T1,typename T2>
struct traits<std::pair<T1,T2> > {
        static std::pair<T1,T2> get(foo &f)
        {
                T1 x=...; …
Run Code Online (Sandbox Code Playgroud)

c++ templates specialization

7
推荐指数
1
解决办法
5194
查看次数

G ++为未使用的模板特化生成代码?

在我正在研究的项目的一些序列化代码中,我有一个类型,其大小取决于编译器.为了解决这个问题,我决定使用模板专业化,这非常有效.一切都在编译时解决.代码看起来有点像这样(不是真正的代码,只是一个例子):

template <int size>
void
special_function()
{
     std::cout << "Called without specialization: " << size << std::endl;
}

template <>
void
special_function<4>()
{
     std::cout << "dword" << std::endl;
}

template <>
void
special_function<8>()
{
     std::cout << "qword" << std::endl;
}

int
main()
{
     special_function<sizeof(int)>();
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我的32位系统上dword,按预期执行上述程序输出.但这样做的全部意义并不仅仅是if (sizeof(int) == 4) { ... } else if ...我希望编译器只为适当的函数生成代码.由于special_function<4>是这个程序中唯一调用的,我希望它是编译器生成的唯一一个(在本例中为gcc 4.1.2,在x86 Linux上).

但这不是观察到的行为.

虽然它确实有效,但每个模板专业化的代码都会生成,尽管从未使用过.但是,不生成通用定义.

我应该提一下,这是一步编译,而不是编译到中间对象文件后跟一个链接.在这种情况下,将死代码删除推迟到链接阶段似乎很自然,我知道链接器并不总是非常擅长这一点.

有谁知道发生了什么?我在这里缺少模板专业化的微妙之处吗?上帝知道魔鬼在C++的细节中.

编辑:因为它已被提及,这种行为发生在-O3和-Os.

EDIT2:Rob建议将函数放在匿名命名空间中.这样做并使用任何级别的优化进行编译确实会删除死代码,这很好.但我很好奇,所以我尝试用以下程序做同样的事情:

namespace {
void foo() { std::cout << "Foo!" << …
Run Code Online (Sandbox Code Playgroud)

c++ templates g++ specialization

7
推荐指数
1
解决办法
1335
查看次数

参数值相等时的模板特化

我有一个表格的功能

template<int a, int b>
void f();
Run Code Online (Sandbox Code Playgroud)

当a == b时,我想专攻.伪代码看起来像:

template<int a>
void f<a, a>(){ //something}

template<int a, int b>
void f<a, b>(){ //something different}
Run Code Online (Sandbox Code Playgroud)

这是否可能没有部分模板专业化问题?

编辑:感谢您的快速回复.该方法实际上是在类中,更像是这样:

<typename a> class A{ 
    template<int b, int c> f(); 
}; 

A inst; 
inst.f<1,1>(); 
inst.f<1,2>(); 
Run Code Online (Sandbox Code Playgroud)

c++ templates specialization template-specialization

7
推荐指数
1
解决办法
1290
查看次数

类模板特化中的静态成员函数

我正在努力访问类模板中定义的静态成员函数.在头文件TemplateTest.h中,我将主类模板定义为:

#include<iostream>

template<class T, class U>
struct TemplateTest
{
public:
    void static invoke();
    /*{

        std::cout << "Should not be called" << std::endl;

    }*/
};
Run Code Online (Sandbox Code Playgroud)

然后源文件TemplateTester.cpp我把一个专业化:

#include "TemplateTest.h"

template<>
struct TemplateTest<int, bool>
{
    static void invoke()
    {
        std::cout << "invoke<int, bool>" << std::endl;   
    }
};

template struct TemplateTest<int, bool>; //instantiate to resolve linker issue
Run Code Online (Sandbox Code Playgroud)

我明确地实例化了类,因此链接器正确解析.

在驱动程序driver.cpp中:

include "TemplateTest.h"

int main()
{
    TemplateTest<int, bool>::invoke();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我使用g ++编译TemplateTest.cpp时,它会正确生成目标文件,但是当我尝试将其链接到驱动程序类时,它会给我的链接器错误"未定义引用`TemplateTest :: invoke()"

我经历了像这样的其他相关帖子,但我没有尝试访问功能模板.

任何线索都非常感谢.

c++ static templates instantiation specialization

7
推荐指数
1
解决办法
3338
查看次数

C++中基于类型的模板函数

我想写一个故障安全访问的函数std::map.

在我的代码中的许多地方我想访问一个std::map按键,但是如果密钥不存在,我希望有一种默认值而不是异常(这是很多"无"的代码).

我写了这个基于模板的功能

template <typename T1, typename T2>
T2 mapGetByKey(std::map<T1, T2>& map, T1 key, T2 defaultValue={})
{
    auto it = map.find(key);

    if (it != map.end())
    {
        return it->second;
    }

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

它很棒.但对于std::map<int, const char*>我想要有不同的行为.所以我可以添加这个专业化:

template <typename T1>
const char* mapGetByKey(std::map<T1, const char*>& map, T1 key, const char* defaultValue="")
{
    auto it = map.find(key);

    if (it != map.end())
    {
        return it->second;
    }

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

它也有效.但我认为这只是一个案例的代码.

有没有人知道如何保存行而不设置defaultValue来""进行调用std::map<int, const char*>

有没有办法在编译时区分类型,可能有一些 …

c++ templates specialization differentiation

7
推荐指数
1
解决办法
105
查看次数