当给出默认模板参数时,将选择什么模板值?

时间:2013-02-23 19:52:06

标签: c++ templates

例如,我有以下模板功能:

template<class IntType = typename boost::uintmax_t>
IntType someFunnyFunc(IntType x, IntType y, IntType z) { ... }

现在我有以下代码:

int main() {
    short a=1, b=2, c=3;
    someFunnyFunc(a, b, c);
    return 0;
}

所有编译器都会生成函数

boost::uintmax_t someFunnyFunc(boost::uintmax_t x, boost::uintmax_t y, boost::uintmax_t z) { ... }

,因为short可以转换为boost :: uintmax_t,或者某些编译器会生成

short someFunnyFunc(short x, short y, short z) {...}

我需要这个,因为当我使用短整数而不是大整数时,我的算法使用循环,循环更频繁。

你可能会问,为什么我不单独定义boost::uintmax_t someFunnyFunc(boost::uintmax_tx, boost::uintmax_t y, boost::uintmax_tz) { ... }并完成它。 我这样做,因为我想使用自定义整数类型,这样就可以使用平台不直接支持的更大的整数。

编辑: 这可以解决我的问题:

template<class IntType>
IntType someFunnyFunc(IntType x, IntType y, IntType z) { ... }

boost::uintmax_t someFunnyFunc(boost::uintmax_t x, boost::uintmax_t y, boost::uintmax_t z) {
    return someFunnyFunc<boost::uintmax_t>(x, y, z);
}

1 个答案:

答案 0 :(得分:2)

编译器不会执行类型转换。他们将产生:

short someFunnyFunc(short x, short y, short z)

简而言之,编制者选择“阻力最小的路径”。在执行类型转换时存在“阻力”,但在生成与您的参数完全匹配的函数签名时没有“阻力”。

如果存在多个相等“阻力”的路径,则可能会出现歧义(或无匹配函数)错误(编译器应采用哪条路径?)。例如,如果您尝试传递shortintlongyou'll get an error,因为您尝试执行的操作没有正确的匹配签名。编译器无法推断出函数的正确类型,因为有几种可能性,它们都不是“最佳”。

编辑:不,这不会解决您的问题。如果您传递short s,编译器将选择模板化函数(并使用IntType = short)。

如果您想使用someFunnyFunc<boost::uintmax_t>(short_1, short_2, short_3);但是传递boost::uintmax_t个参数,则可以short。你也可以这样做:

template<class IntType>
IntType someFunnyFunc(IntType x, IntType y, IntType z) { ... }

// If you try to pass shorts, the compiler will opt for this version:
boost::uintmax_t someFunnyFunc(short x, short y, short z) {
    return someFunnyFunc<boost::uintmax_t>(x, y, z);
}

假设您要使用boost::uintmax_t但仍然传递short s。