関数テンプレートのtrick
関数テンプレートのtrick
gccにメンバー関数テンプレートのtrickをサポートさせる
羅朝輝(http://www.cnblogs.com/kesalin/)
本文は「
署名-非商業用途-一貫性を保つ」クリエイティブ・パブリック・プロトコル
gcc 4.7.3メンバー関数テンプレートの特化はサポートされていません.次のコードがあります.
VS 2010でのコンパイル運転は問題ないが、gcc 4.7である.3では、コンパイルは通じません.
?
近似メンバー関数テンプレートの特化の効果を達成するために、メンバー関数のメインテンプレートとリロード関数を使用して実現できます.
呼び出しDoTest()の実行結果は次のとおりです.
注意:
VS 2010バージョンのコードは、テンプレートパラメータがTであり、インスタンス化では暗黙的なタイプ変換は行われません.つまり、Derived*を実パラメータとして呼び出したのは、Base*特化バージョンではなくメインテンプレートです.
一方,gccではテンプレートパラメータもTであるが,重荷決定に影響するfunctionパラメータはDummyIdentityであり,このテンプレートを異なる実際のパラメータでインスタンス化し,重荷関数の山を得た.したがって,Derived*を実パラメータとして用いる場合,呼び出される関数は当然インスタンス化されたvoid function(DummyIdentity)である.
分類:
C/C++
ラベル:
C++ ,
gcc ,
template
gccにメンバー関数テンプレートのtrickをサポートさせる
羅朝輝(http://www.cnblogs.com/kesalin/)
本文は「
署名-非商業用途-一貫性を保つ」クリエイティブ・パブリック・プロトコル
gcc 4.7.3メンバー関数テンプレートの特化はサポートされていません.次のコードがあります.
#ifndef __MEMFUNTEMPLATE_H__
#define __MEMFUNTEMPLATE_H__
#include <stdio.h>
class Base {};
class Derived : public Base {};
struct Functor {
template <typename T> void function() {
printf(" Primary template....
");
}
template<>
void function<int>(){
printf(" Specialization for int....
");
}
template<> void function<Base *>() {
printf(" Specialization for Base *....
");
}
};
class Tester {
public:
static void DoTest()
{
Functor functor;
functor.function<char>();
functor.function<int>();
functor.function<Base *>();
functor.function<Derived *>();
}
};
#endif // __MEMFUNTEMPLATE_H__
VS 2010でのコンパイル運転は問題ないが、gcc 4.7である.3では、コンパイルは通じません.
?
../src/MemFunTemplate.h:21:14: error: <strong>
explicit
specialization in non-
namespace
scope</strong> ‘
struct
Functor’
../src/MemFunTemplate.h:22:24: error:
template
-id ‘function<
int
>’ in declaration of primary
template
../src/MemFunTemplate.h:26:14: error:
explicit
specialization in non-
namespace
scope ‘
struct
Functor’
../src/MemFunTemplate.h:26:38: error:
template
-id ‘function<Base*>’ in declaration of primary
template
../src/MemFunTemplate.h:26:21: error: ‘
void
Functor::function()’ cannot be overloaded
../src/MemFunTemplate.h:22:10: error: with ‘
void
Functor::function()’
../src/MemFunTemplate.cpp: In function ‘
int
main()’:
../src/MemFunTemplate.cpp:17:2: error: ‘DoTest’ is not a member of ‘Functor’
近似メンバー関数テンプレートの特化の効果を達成するために、メンバー関数のメインテンプレートとリロード関数を使用して実現できます.
/*
* MemFunTemplate.h
*
* Created on: Jul 12, 2013
* Author: http://blog.csdn.net/kesalin/
*/
#ifndef MEMFUNTEMPLATE_H_
#define MEMFUNTEMPLATE_H_
#include <stdio.h>
template<typename T>
struct DummyIdentity {
typedef T type;
};
class Base {};
class Derived : public Base {};
struct Functor {
template <typename T> void function() {
function(DummyIdentity<T>());
}
private:
template <typename T>
void function(DummyIdentity<T>) {
printf(" Primary template DummyIdentity<T>....
");
}
void function(DummyIdentity<int>) {
printf(" overload function for DummyIdentity<int>....
");
}
void function(DummyIdentity<Base *>) {
printf(" overload function for DummyIdentity<Base *>....
");
}
};
class Tester {
public:
static void DoTest()
{
Functor functor;
functor.function<char>();
functor.function<int>();
functor.function<Base *>();
functor.function<Derived *>();
}
};
#endif /* MEMFUNTEMPLATE_H_ */
呼び出しDoTest()の実行結果は次のとおりです.
Primary template DummyIdentity<T>....
overload function for DummyIdentity<int>....
overload function for DummyIdentity<Base *>....
Primary template DummyIdentity<T>....
注意:
VS 2010バージョンのコードは、テンプレートパラメータがTであり、インスタンス化では暗黙的なタイプ変換は行われません.つまり、Derived*を実パラメータとして呼び出したのは、Base*特化バージョンではなくメインテンプレートです.
一方,gccではテンプレートパラメータもTであるが,重荷決定に影響するfunctionパラメータはDummyIdentity
分類:
C/C++
ラベル:
C++ ,
gcc ,
template