相关疑难解决方法(0)

模板偏序 - 为什么部分演绎在这里成功

考虑以下简单(在模板问题的范围内)示例:

#include <iostream>

template <typename T>
struct identity;

template <>
struct identity<int> {
    using type = int;
};

template<typename T> void bar(T, T ) { std::cout << "a\n"; }
template<typename T> void bar(T, typename identity<T>::type) { std::cout << "b\n"; }

int main ()
{
    bar(0, 0);
}
Run Code Online (Sandbox Code Playgroud)

clang和gcc都在那里打印"a".根据[temp.deduct.partial]和[temp.func.order]中的规则,为了确定部分排序,我们需要合成一些独特的类型.所以我们有两次尝试扣除:

+---+-------------------------------+-------------------------------------------+
|   | Parameters                    | Arguments                                 |
+---+-------------------------------+-------------------------------------------+
| a | T, typename identity<T>::type | UniqueA, UniqueA                          |
| b | T, T                          | UniqueB, typename identity<UniqueB>::type |
+---+-------------------------------+-------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

根据Richard Corden的回答 …

c++ templates partial-ordering language-lawyer overload-resolution

20
推荐指数
2
解决办法
1166
查看次数

为什么非模板化函数具有相同的名称和参数但返回类型不同是非法的?(但模板功能合法吗?)

我查看了一些相关的堆栈溢出线程,例如模板函数重载的这种情况,这让我无法理解

和

函数重载按返回类型?

但似乎都没有给我我正在寻找的答案,至少不是一种容易让我解释的方式.

我的问题归结为:从设计和技术的角度来看,为什么这样做是合法的:

#include <iostream>

using namespace std;

template<class T>
void func(){
    cout << "Compiler inferred from void return value!\n";
}

template<class T>
int func(){
    cout << "Compiler inferred from int return value!\n";
    return 0;
}

int main(){
    void (*thisFunc)()=func<int>;
    int (*thatFunc)()=func<int>;
    thisFunc();
    thatFunc();
}
Run Code Online (Sandbox Code Playgroud)

但不是这个:

#include <iostream>

using namespace std;

void func(){
    cout << "You won't see this because it won't compile!\n";
}

int func(){
    cout << "Nor this one!\n";
    return 0;
}

int main(){
    void …
Run Code Online (Sandbox Code Playgroud)

c++ templates overloading ambiguity

11
推荐指数
1
解决办法
329
查看次数

为什么函数重载模糊,但模板重载不模糊?

在下面,为什么调用bar不明确的实例化,而非模板重载函数foo是不明确的.nullptr取而代之的是相同的NULL

#include <iostream>

template<typename T>
void bar (T*)
{
  std::cout << "bar(T*)" << std::endl;
}

template<typename T>
void bar (typename T::value_type *)
{
  std::cout << "bar(T::value_type*)" << std::endl;
}

struct A
{
  using value_type = int;
};

void foo (A::value_type*)
{
  std::cout << "foo(A::value_type *)" << std::endl; 
}

void foo (A*)
{
  std::cout << "foo(A *)" << std::endl; 
}

int main ()
{
  bar<A> (NULL);
  foo (NULL); // ambigous
}
Run Code Online (Sandbox Code Playgroud)

编辑:要清楚.我希望foo过载是模棱两可的.我不明白为什么 …

c++ templates overload-resolution

6
推荐指数
1
解决办法
487
查看次数

可变参数模板构造函数的扣除指南失败

我试图重现视频C++ Weekly - Ep 48 - C++ 17的Variadic的结果using,但失败了.问题可以简化为以下代码段.

假设我有这样的通用结构:

template <class... T>
struct Container {
    template <class... U>
    Container(U... us) {}
};
Run Code Online (Sandbox Code Playgroud)

现在我可以Container用任何参数初始化a ,比如

auto d = Container(1,2,3);
Run Code Online (Sandbox Code Playgroud)

但是,编译器永远不会知道它是什么类型d.要解决这个问题,我们应该提供一个扣除指南,例如

template <class... U>
Container(U...) -> Container<double, int, bool>
Run Code Online (Sandbox Code Playgroud)

根据视频,编译器现在应该知道d有类型Container<double, int, bool>.

但是,代码无法按预期工作.打印时typeid(d).name(),无论我如何更改演绎指南中的返回类型,输出将始终被9ContainerIJEE转换为Container<>,表明此指南根本不指导编译器.

我正在使用gcc-7-snapshot-20170402,视频中的编译器是gcc-7-snapshot-20170130.

谁能告诉我这里有什么问题?

更新:

顺便说一句,如果我明确写

Container<bool, int> d = Container(1,2,3);
Container<char, char, char> d = Container(1,2,3);
...
Run Code Online (Sandbox Code Playgroud)

代码将始终编译,并提供像9containerIJbiEE …

c++ gcc c++17

6
推荐指数
1
解决办法
899
查看次数