我有以下代码(抱歉大代码块,但我不能再缩小它)
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) 我有一个模板化的类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)?
我从我的生产项目中提取了以下最小示例。我的机器学习项目由线性代数库、深度学习库和应用程序组成。
线性代数库包含一个基于可存储向量的矩阵模块:
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) 假设您有一个班级,他们的工作就是连接到远程服务器.我想抽象这个类来提供两个版本,一个通过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的代码问题,现在必须在两个专用版本中编写和维护,它们最终都是相同的.如何最好地解决这个问题?我有一种感觉,我认为这一切都错了.
我想专门研究以下成员函数:
class foo {
template<typename T>
T get() const;
};
Run Code Online (Sandbox Code Playgroud)
对于bar依赖于模板的其他类.
例如,我想bar是std::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) 在我正在研究的项目的一些序列化代码中,我有一个类型,其大小取决于编译器.为了解决这个问题,我决定使用模板专业化,这非常有效.一切都在编译时解决.代码看起来有点像这样(不是真正的代码,只是一个例子):
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) 我有一个表格的功能
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) 我正在努力访问类模板中定义的静态成员函数.在头文件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()"
我经历了像这样的其他相关帖子,但我没有尝试访问功能模板.
任何线索都非常感谢.
我想写一个故障安全访问的函数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*>?
有没有办法在编译时区分类型,可能有一些 …
specialization ×10
c++ ×8
templates ×8
constructor ×1
g++ ×1
gcc ×1
haskell ×1
oop ×1
performance ×1
static ×1