C++ 禁止自动类型推断

C++ 禁止自动类型推断,c++,templates,overload-resolution,C++,Templates,Overload Resolution,我有以下演示代码: template <int i, typename T, typename U> T func(const U &t){return i * t;} template <int i, typename T> T func(const T &t){return 2 * i * t;} int main() { return func<1, int>(1); } 因此,很明显,自动类型推断(针对模板参数U)

我有以下演示代码:

template <int i, typename T, typename U>
T func(const U &t){return i * t;}

template <int i, typename T>
T func(const T &t){return 2 * i * t;}

int main()
{
        return func<1, int>(1);
}
因此,很明显,自动类型推断(针对模板参数U)干扰了我选择正确版本的模板函数(只有2个参数)的兴趣

我需要两个版本都有一个基本的和一个专门的模板,它们做的事情有点不同


因此,问题是:是否有可能告诉编译器此时不要自动推断类型(例如,通过某种方式说:使用只有2个参数的模板)?

您不能禁用类型推断,但可以使用SFINAE禁止其中一个重载:

template <int N, typename T, typename U>
typename std::enable_if< !std::is_same<T,U>::value, T >::type
func( const U & t ) {
   return i*t;
}
模板
typename标准::如果<,则启用!std::is_same::value,T>::type
职能(施工及测试){
返回i*t;
}
这基本上创建了一个模板函数,如果推断的类型
U
是类型
T
,则替换将失败,此时SFINAE将从潜在候选集删除该模板,并拾取另一个模板


如果没有启用C++11的编译器,
enable\u If
是相同的
模板很容易编写。。。只需在谷歌上搜索它们或删除注释。

您可以传递一个初始值设定项列表,该列表有效地禁用了推断(但会导致参数列表初始化,但在本例中,
int
具有相同的效果):


你是说除了显而易见的?(这是给函数模板赋予不同的名称——如果您需要自己做一些事情来指导编译器使用哪个模板,那么使用相同的名称有什么意义?)这将是最后一个选择,但我希望函数共享相同的名称。我还建议通过重命名进行重新设计。对我来说,这似乎是一种非常糟糕的代码气味。人们已经很容易被使用重载集的哪个函数的问题弄糊涂了。如果出现类似的情况,则会使问题变得更加困难,并可能导致以后的代码无法维护。这可能会解决我的问题,但无法回答问题。也许你对此也有答案?类型推断是语言的一部分,你不能仅仅禁用它。您可以在某些情况下(如上所述)禁用重载,以便在某些情况下不会考虑它。可能我应该使用另一种措辞。我不是指自动类型推断,而是指模板参数是自动设置的。所以基本上我是在要求一个语法来告诉编译器:使用这个参数签名的模板@没人:那正是类型推断。如果没有类型推断,您必须提供所有模板参数,并且在您的情况下,因为您只有两个参数,所以不会造成任何歧义。我认为这正是我所要求的。虽然我现在回避了这个问题,但我认为这更适合这个问题。
template <int N, typename T, typename U>
typename std::enable_if< !std::is_same<T,U>::value, T >::type
func( const U & t ) {
   return i*t;
}
template <int i, typename T, typename U>
T func(const U &t){return i * t;}

template <int i, typename T>
T func(const T &t){return 2 * i * t;}

int main()
{
        return func<1, int>({1});
}
template <int i, typename T, typename U>
T func(typename std::common_type<const U &t>::type t){return i * t;}

template <int i, typename T>
T func(const T &t){return 2 * i * t;}

int main()
{
        return func<1, int>({1});
}