这个嵌套模板基类是不明确的?

时间:2017-04-29 03:00:39

标签: c++ templates variadic-templates crtp template-deduction

此代码用于在Clang 3.8中编译,仍然在VS 2017中编译,但在Clang 3.9中开始发出错误。

template <typename D, typename ... I>
struct impl : I ...
{};

template <typename D, typename ... I>
void f(impl<D, I...> const&)
{}

struct A : impl<A> {};
struct B : impl<B, A> {};

int main()
{
    f(A());
    f(B()); // Error
}

Clang 3.9说

<source>:15:5: error: no matching function for call to 'f'
    f(B());
    ^
<source>:6:6: note: candidate template ignored: failed template argument deduction
void f(impl<D, I...> const&)
     ^

所有三个编译器都在运行: https://godbolt.org/g/OKFpPl

我希望f(A())推断D = A, I... = <>f(B())推导D = B, I... = A,然后将其impl推断为impl。我的最终目标是检测impl参数包中的类型,这些参数包本身就是$x = "Hello World!"; include_once('includes/tbszip.php'); $zip = new clsTbsZip(); // Open the document $zip->Open('mydoc.docx'); $content = $zip->FileRead('word/document.xml'); $p = strpos($content, '</w:body>'); if ($p===false) exit("Tag </w:body> not found in document."); // Add the text at the end $content = substr_replace($content, '<w:p><w:r><w:t>'.$x.'</w:t></w:r></w:p>', $p, 0); $zip->FileReplace('word/document.xml', $content, TBSZIP_STRING); // Save as a new file $zip->Flush(TBSZIP_FILE, 'newfile.pdf'); 的实例。我是以错误的方式解决这个问题吗?

1 个答案:

答案 0 :(得分:4)

不确定但......

您的B类继承自impl<B, A>继承的impl<A>

所以B继承了一对不同的impl<D, I...>基类,因此类型演绎是暧昧的(D == BI... == <A>D == A和{{ 1}})。

所以我认为clang 3.8是错误的,3.9是对的。

  

我的最终目标是检测impl参数包中的类型,这些类型本身就是impl的实例。我是以错误的方式解决这个问题吗?

是的,你这样做是错误的(我认为)。