【发布时间】:2012-11-11 08:25:39
【问题描述】:
在使用 GCC 4.7.2 和 Clang 3.1 编译一些 C++11 代码时,我遇到了一个问题,即 Clang 无法推断出 GCC 成功的模板参数。 在更抽象的形式中,代码如下所示:
src/test.cc:
struct Element {
};
template <typename T>
struct FirstContainer {
};
template <typename T, typename U = Element>
struct SecondContainer {
};
template <template <typename> class Container>
void processOrdinary(Container<Element> /*elements*/) {
}
template <template <typename, typename> class Container>
void processOrdinary(Container<Element, Element> /*elements*/) {
}
template <template <typename, typename...> class Container>
void processVariadic(Container<Element> /*elements*/) {
}
int main() {
// This function instantiation works in both GCC and Clang.
processOrdinary(FirstContainer<Element>{});
// This function instantiation works in both GCC and Clang.
processOrdinary(SecondContainer<Element>{});
// This function instantiation works in both GCC and Clang.
processVariadic(FirstContainer<Element>{});
// This function instantiation works in both GCC and Clang.
processVariadic<SecondContainer>(SecondContainer<Element>{});
// This function instantiation works in GCC but not in Clang.
processVariadic(SecondContainer<Element>{});
return 0;
}
通过阅读第 14.3.3 节中的示例和标准第 14.8.2 节中的规范,我认为推论应该有效,但我不能肯定地说。这是我从构建中得到的输出:
mkdir -p build-gcc/
g++ -std=c++0x -W -Wall -Wextra -Weffc++ -pedantic -c -o build-gcc/test.o src/test.cc
g++ -o build-gcc/test build-gcc/test.o
mkdir -p build-clang/
clang++ -std=c++11 -Weverything -Wno-c++98-compat -c -o build-clang/test.o src/test.cc
src/test.cc:34:3: error: no matching function for call to 'processVariadic'
processVariadic(SecondContainer<Element>{});
^~~~~~~~~~~~~~~
src/test.cc:21:6: note: candidate template ignored: failed template argument deduction
void processVariadic(Container<Element> /*elements*/) {
^
1 error generated.
make: *** [build-clang/test.o] Fel 1
为什么结果不同? GCC 是马虎、Clang 笨,我的代码是否包含未指定的行为或全部?
【问题讨论】:
-
我同意你的看法。我在 C++11 最终草案中看到的所有内容都表明这应该可行。 14.3.3.3 尤其相关。
-
您的示例缺少
typedef int Element;,对吗? -
不,在代码的开头我定义了一个名为 Element 的结构。
-
您是否尝试将其发布到 clang/llvm 邮件列表?他们可能对此有更深入的了解,并且很高兴知道他们的实施是否不完整。
标签: c++ gcc c++11 clang variadic-templates