ソース(質問の最後)は、Solaris Studio(他のコンパイラではなく)でのマングリングエラーであると私が信じているものを引き起こします。
わかりやすくするために、エラー メッセージは新しい行で再フォーマットされました。
"overload.cpp", line 44: Error:
runGenEntries<std::vector<int>>(const GenEntryRuleDriven<int>&, const std::vector<int>&)
and
runGenEntries<std::vector<int>>(const GenEntryRulesDriven<int>&, const std::vector<int>&)
have same extern name
"__1cNrunGenEntries4nDstdGvector4Cin0AJallocator4Ci_____6FrkTArk1_v_".
1 Error(s) detected.
2 つの関数 runGenEntries の最初のパラメーターが 1 文字 (Rule の末尾の「s」) だけ異なることに注意してください。
これは、最初のパラメーターのタイプが次の場合に発生するようです。
const typename GenEntryRulesDrivenType<typename InputsType::value_type>::type
また、最初のパラメーターがタイプの代わりにある場合は発生しません:
const typename GenEntryRulesDriven<typename InputsType::value_type>
最終的に同じタイプに解決されます。
これは、Solaris だけに実装されているあいまいな C++ ルールの結果ですか? それとも、シンボルをマングルするときの Solaris Studio のバグですか?
完全なソース
次のソースは、どのコンパイラでもそのままコンパイルできます。
定義は、エラーを引き起こすコードをアクティブにするか、同じ結果を生成するはずのコードをアクティブにします (ただし、今回はバグなし):
#include <iostream>
#include <vector>
template<typename T>
struct GenEntryRulesDriven
{
void foo() const
{
}
};
template<typename T>
struct GenEntryRuleDriven
{
void bar() const
{
}
std::string toto; // to have a different size than GenEntryRulesDriven
};
template <typename T>
struct GenEntryRulesDrivenType
{
typedef GenEntryRulesDriven<T> type;
};
template <typename T>
struct GenEntryRuleDrivenType
{
typedef GenEntryRuleDriven<T> type;
};
#if 1 // Gives an error
template <typename InputsType>
void runGenEntries(const typename GenEntryRulesDrivenType<
typename InputsType::value_type>::type &genEntry,
const InputsType& inputs)
{
genEntry.foo();
}
template <typename InputsType>
void runGenEntries(const typename GenEntryRuleDrivenType<
typename InputsType::value_type>::type &genEntry,
const InputsType& inputs)
{
genEntry.bar();
}
#else // No error but same types as above!
template <typename InputsType>
void runGenEntries(const typename GenEntryRulesDriven<
typename InputsType::value_type> &genEntry,
const InputsType& inputs)
{
genEntry.foo();
}
template <typename InputsType>
void runGenEntries(const typename GenEntryRuleDriven<
typename InputsType::value_type> &genEntry,
const InputsType& inputs)
{
genEntry.bar();
}
#endif
int
main()
{
std::vector<int> v;
GenEntryRulesDriven<int> rulesDriven;
runGenEntries(rulesDriven, v);
GenEntryRuleDriven<int> ruleDriven;
runGenEntries(ruleDriven, v);
return 0;
}
このコードは、次のプラットフォームでコンパイルされました。
bash$ uname -a
SunOS pegasus 5.10 Generic_118855-33 i86pc i386 i86pc
bash$ CC -V
CC: Sun C++ 5.10 SunOS_i386 128229-07 2010/03/24