源代码(在问题的末尾)会引发我认为是 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.
注意两个函数 runGenEntries 的第一个参数仅相差一个字符(规则末尾的“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