部分排序变量模板函数clang

时间:2015-04-11 14:49:47

标签: c++ templates c++11 boost-program-options partial-ordering

我目前正在玩一个使用Boost.ProgramOptions的项目,我不得不创建以下结构来为选项添加一些约束:

template <const char *str1, const char*... str2> 
struct restrictedValues
{
...
};

为了验证新选项,您必须重载boost::program_options::validate函数:

template<class T, class charT>                                                                            
void validate(boost::any& v, const std::vector< std::basic_string<charT> >& xs, T*, long);

此验证功能的调用如下:

validate(value_store, new_tokens, (T*)0, 0);

由boost预先确定:&#34;目标类型是通过一个参数指定的,该参数具有指向所需类型的指针类型。这是没有部分模板排序的编译器的解决方法,就像最后一个&long; int / int&#39; 。参数&#34;

因此,我以下列方式编写了我的验证版本:

template<class charT, const char *... str>
void validate(boost::any &v,
        const std::vector<std::basic_string<charT> >& values,
        restrictedValues<str...>* /*target_type*/,
        int /*unused*/) { ... }

看起来我的clang版本(Ubuntu clang版本3.5.0-4ubuntu2~trusty2(标签/ RELEASE_350 / final)(基于LLVM 3.5.0))只是跳过我的版本并在默认版本中优雅地失败。虽然我的gcc((Ubuntu 4.8.2-19ubuntu1)4.8.2)很高兴编译。

编辑查看显示不同行为的实际示例,来自@dyp:

Live On Coliru

#include <boost/any.hpp>
#include <vector>
#include <string>
#include <iostream>

template <const char *str1, const char*... str2> struct restrictedValues                                                                                
{
/*...*/
};

template<class T, class charT>                                                                            
void validate(boost::any&, const std::vector< std::basic_string<charT> >&, T*, long)
{
    std::cout << "default version\n";
}

extern char const client[] = "hello";
extern char const server[] = "world";

template<class charT, const char *... str>
void validate(boost::any &,
        const std::vector<std::basic_string<charT> >&,
        restrictedValues<str...>* /*target_type*/,
        int /*unused*/) {
    std::cout << "custom version\n";
}

int main()
{
    boost::any a;
    std::vector<std::string> xs;
    restrictedValues<client, server>* p = 0;
    validate(a, xs, p, 0);
}

此外,对于结构/函数使用非可变参数模板(固定数量的const char *)的相同过程确实像魅力一样。

我不太确定哪个查找过程会导致这种模糊错误。 如果我的函数没有使用模板,则会根据重载规则选择它,但情况并非如此。通过阅读模板函数的部分排序规则,两个函数对模板参数具有相同的特化,但我的期望是int / long技巧应该起作用。关于如何解决这个模板之谜的任何想法?

1 个答案:

答案 0 :(得分:0)

这里通常的方法是使用强类型定义来使ADL工作。

我在旧答案中记录了这一点¹:


¹第一条评论已经过时,请参考我以前的旧答案。