テンプレートパラメータに応じてメソッドシグネチャが変化するクラステンプレートを作成しようとしています。私の目標は、コードの重複をできるだけ少なくすることです。この例を考えてみましょう。最初にクラス宣言を行います。
// a.hxx
#ifndef A_HXX
#define A_HXX
template<typename T>
struct A
{
void foo(T value) const;
void bar() const;
};
#include <string>
#ifndef short_declaration
template<>
struct A<std::string>
{
void foo(const std::string &value) const;
void bar() const;
};
#else // short_declaration
template<>
struct A<std::string>
{
void foo(const std::string &value) const;
};
#endif // short_declaration
#endif // A_HXX
次に、クラス定義:
// a_impl.hxx
#ifndef A_IMPL_HXX
#define A_IMPL_HXX
#include "a.hxx"
#include <iostream>
#include <typeinfo>
template<typename T>
void A<T>::foo(T value) const
{
std::cout << "A<T=" << typeid(T).name() << ">::foo(" << value << ")"
<< std::endl;
}
template<typename T>
void A<T>::bar() const
{
std::cout << "A<T=" << typeid(T).name() << ">::bar()" << std::endl;
}
void A<std::string>::foo(const std::string &value) const
{
std::cout << "A<std::string>::foo(" << value << ")" << std::endl;
}
#ifndef skip_duplicates
void A<std::string>::bar() const
{
std::cout << "A<std::string>::bar()" << std::endl;
}
#endif // skip_duplicates
#endif // A_IMPL_HXX
そして今、テストプログラム:
// test.cxx
//#define skip_duplicates
//#define short_declaration
#include "a_impl.hxx"
int main(void)
{
A<int> obj1;
A<std::string> obj2;
int value1(1);
std::string value2("baz");
obj1.foo(value1);
obj1.bar();
obj2.foo(value2);
obj2.bar();
return 0;
}
このようにコンパイルすると、(typeidの実装に対して)期待される出力が得られます。
A<T=i>::foo(1)
A<T=i>::bar()
A<std::string>::foo(baz)
A<std::string>::bar()
しかし、もちろん、どちらか、skip_duplicates
またはshort_declaration
私の例でも有効にする方法が欲しいです。やや似たような質問に対して、ecatmurは、クラス全体を指定する必要があるため、少なくとも定義short_declaration
は機能しないと回答しました。
大きなオブジェクトを引数として取る可能性のあるメソッドを使用してクラステンプレートを作成する問題を他の人がどのように処理しますか?